Subject: Appending unmatched and override matched values
Posted By: ShaileshShinde Post Date: 4/24/2008 12:32:17 AM
Hi All,
I have an requirenment to merge two xml files based on the values....

Both the xml, which contains table structure like below....

main file(File1.xml)...

<?xml version="1.0" encoding="utf-8"?>
<dita>
  <topic>
    <title>Terms</title>
    <body/>
    <reference>
      <title>Localizable</title>
      <refbody class="- topic/body        reference/refbody ">
        <table>
          <tgroup cols="2" colsep="0" rowsep="1" outputclass="2col.small.table" class="- topic/tgroup ">
            <colspec colnum="1" colname="1" colwidth="1.167in" colsep="0" class="- topic/colspec "/>
            <colspec colnum="2" colname="2" colwidth="2.041in" colsep="0" class="- topic/colspec "/>
            <thead class="- topic/thead ">
              <row rowsep="1" class="- topic/row ">
                <entry colname="1" colsep="1" class="- topic/entry ">
                  <p translate="no" class="- topic/p ">Key (or Paragraph tag)</p>
                </entry>
                <entry colname="2" colsep="1" class="- topic/entry ">
                  <p translate="no" class="- topic/p ">Value</p>
                </entry>
                <entry colname="3" class="- topic/entry ">
                  <p translate="no" class="- topic/p ">Comment</p>
                </entry>
              </row>
            </thead>
            <tbody class="- topic/tbody ">
              <row rowsep="1" class="- topic/row ">
                <entry colname="1" colsep="1" class="- topic/entry ">
                  <p translate="no" class="- topic/p ">Test1</p>
                </entry>
                <entry colname="2" colsep="1" class="- topic/entry ">
                  <p class="- topic/p ">Test1</p>
                </entry>
                <entry colname="3" class="- topic/entry ">
                  <draft-comment class="- topic/draft-comment ">
                    <p class="- topic/p ">Test1 text</p>
                  </draft-comment>
                </entry>
              </row>
              <row rowsep="1" class="- topic/row ">
                <entry colname="1" colsep="1" class="- topic/entry ">
                  <p translate="no" class="- topic/p ">Test2</p>
                </entry>
                <entry colname="2" colsep="1" class="- topic/entry ">
                  <p class="- topic/p ">Test2</p>
                </entry>
                <entry colname="3" class="- topic/entry ">
                  <draft-comment class="- topic/draft-comment ">
                    <p class="- topic/p ">Test2</p>
                  </draft-comment>
                </entry>
              </row>
              <row rowsep="1" class="- topic/row ">
                <entry colname="1" colsep="1" class="- topic/entry ">
                  <p translate="no" class="- topic/p ">Test</p>
                </entry>
                <entry colname="2" colsep="1" class="- topic/entry ">
                  <p class="- topic/p ">Test</p>
                </entry>
                <entry colname="3" class="- topic/entry ">
                  <draft-comment class="- topic/draft-comment ">
                    <p class="- topic/p ">Test</p>
                  </draft-comment>
                </entry>
              </row>
            </tbody>
          </tgroup>
        </adobetable>
      </refbody>
    </reference>
  </topic>
</dita>

file2.xml....
<?xml version="1.0" encoding="utf-8"?>
<dita>
  <topic DTDVersion="V1.1.3" domains="(topic hi-d) (topic pr-d) (topic sw-d) (topic adobe-d)" class="- topic/topic " id="WS58b67d046ae8e03c15f1d0a110e67a7921-8000">
    <title class="- topic/title ">Localizable Terms</title>
    <body class="- topic/body "/>
    <reference DTDVersion="V1.1.3" domains="(topic hi-d) (topic pr-d) (topic sw-d) (topic adobe-d)" class="- topic/topic       reference/reference " id="WS58b67d046ae8e03c15f1d0a110e67a7921-7fff">
      <title class="- topic/title ">Localizable Terms</title>
      <refbody class="- topic/body        reference/refbody ">
        <adobetable frame="all" colsep="0" rowsep="1" class="+ topic/table adobe-d/adobetable ">
          <tgroup cols="2" colsep="0" rowsep="1" outputclass="2col.small.table" class="- topic/tgroup ">
            <colspec colnum="1" colname="1" colwidth="1.167in" colsep="0" class="- topic/colspec "/>
            <colspec colnum="2" colname="2" colwidth="2.041in" colsep="0" class="- topic/colspec "/>
            <thead class="- topic/thead ">
              <row rowsep="1" class="- topic/row ">
                <entry colname="1" colsep="1" class="- topic/entry ">
                  <p translate="no" class="- topic/p ">Key (or Paragraph tag)</p>
                </entry>
                <entry colname="2" colsep="1" class="- topic/entry ">
                  <p translate="no" class="- topic/p ">Value</p>
                </entry>
                <entry colname="3" class="- topic/entry ">
                  <p translate="no" class="- topic/p ">Comment</p>
                </entry>
              </row>
            </thead>
            <tbody class="- topic/tbody ">
              <row rowsep="1" class="- topic/row ">
                <entry colname="1" colsep="1" class="- topic/entry ">
                  <p translate="no" class="- topic/p ">testing</p>
                </entry>
                <entry colname="2" colsep="1" class="- topic/entry ">
                  <p class="- topic/p ">testing</p>
                </entry>
                <entry colname="3" class="- topic/entry ">
                  <draft-comment class="- topic/draft-comment ">
                    <p class="- topic/p ">testing</p>
                  </draft-comment>
                </entry>
              </row>
              <row rowsep="1" class="- topic/row ">
                <entry colname="1" colsep="1" class="- topic/entry ">
                  <p translate="no" class="- topic/p ">read</p>
                </entry>
                <entry colname="2" colsep="1" class="- topic/entry ">
                  <p class="- topic/p ">read</p>
                </entry>
                <entry colname="3" class="- topic/entry ">
                  <draft-comment class="- topic/draft-comment ">
                    <p class="- topic/p ">Test: Text for read</p>
                  </draft-comment>
                </entry>
              </row>
              <row rowsep="1" class="- topic/row ">
                <entry colname="1" colsep="1" class="- topic/entry ">
                  <p translate="no" class="- topic/p ">only</p>
                </entry>
                <entry colname="2" colsep="1" class="- topic/entry ">
                  <p class="- topic/p ">only</p>
                </entry>
                <entry colname="3" class="- topic/entry ">
                  <draft-comment class="- topic/draft-comment ">
                    <p class="- topic/p ">Test: Text for only</p>
                  </draft-comment>
                </entry>
              </row>
              <row rowsep="1" class="- topic/row ">
                <entry colname="1" colsep="1" class="- topic/entry ">
                  <p translate="no" class="- topic/p ">Test1</p>
                </entry>
                <entry colname="2" colsep="1" class="- topic/entry ">
                  <p class="- topic/p ">Test1</p>
                </entry>
                <entry colname="3" class="- topic/entry ">
                  <draft-comment class="- topic/draft-comment ">
                    <p class="- topic/p ">Test1</p>
                  </draft-comment>
                </entry>
              </row>
            </tbody>
          </tgroup>
        </adobetable>
      </refbody>
    </reference>
  </topic>
</dita>


With the below xslt attached code snippet, can able to override from file2 to file1 the row which gets matched, but failing to append row when it's not matched.
xslt...
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>
    <xsl:variable name="overrides" select="'../../bin/term_overrides.xml'"/>
    <xsl:variable name="term2b" select="document($overrides)//tbody/row/entry[1]/p/text()"/>
    <xsl:variable name="term.override" select="document($overrides)//tbody/row"/>
    <xsl:template match="*">
        <xsl:copy>
            <xsl:copy-of select="@*"/>
            <xsl:apply-templates/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="tbody">
        <tbody>
            <xsl:for-each select="row">
                <xsl:variable name="r1" select="entry[1]/p"/>
                <xsl:choose>
                    <xsl:when test="$r1[.=$term2b]">
                        <!-- override matched rows -->
                        <xsl:copy-of select="$term.override[entry[1]/p[.=$r1]]"/>
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:copy-of select="."/>
                    </xsl:otherwise>
                </xsl:choose>
            </xsl:for-each>
        </tbody>
    </xsl:template>
    <xsl:template match="/*">
        <xsl:copy>
            <xsl:apply-templates/>
            <!-- append unmatched rows -->
            <xsl:apply-templates select="//tbody/row[entry[1]/p[.!=$term.override[entry[1]/p/text()]]]"/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

Please suggest what's get wrong in xslt?

Thanks a lot!!!
Shailesh



Reply By: mhkay Reply Date: 4/24/2008 5:46:16 AM
You would be more likely to get a good answer if you simplified the problem - it might also help your own debugging. I think that what's wrong is that your second apply-templates

<xsl:apply-templates select="//tbody/row[entry[1]/p[.!=$term.override[entry[1]/p/text()]]]"/>


is processing nodes in file1 (which have already been processed), whereas at this stage you want to process nodes in file2 that don't match anything in file1. But I may have misunderstood your requirement.

The way I usually tackle this (in XSLT 2.0) is to treat it as a grouping problem. Select all the rows in both documents, group them on your grouping key, and output the first (or last) element in each group.

Michael Kay
http://www.saxonica.com/
Author, XSLT Programmer's Reference and XPath 2.0 Programmer's Reference
Reply By: ShaileshShinde Reply Date: 4/24/2008 6:06:01 AM
Hi mhkay,

Yes, the problem is, i am not getting the rows which does not matched with file1...

I have tried with the below ...
 <xsl:apply-templates select="$term.override[entry[1]/p/text()][.!=//tbody/row[entry[1]/p]]"/>

But this outputs the all the rows present in file2...and after the closing </topic> element.

--
Shailesh


Reply By: mhkay Reply Date: 4/24/2008 6:37:31 AM
That's closer:

 <xsl:apply-templates select="$term.override[entry[1]/p/text()][.!=//tbody/row[entry[1]/p]]"/>

But the //tbody searches within the current document (which is file2 at this point), you need to search within file1; and even if you correct that, your expression is wrong


You want something more like

select="$term.override[not(entry[1]/p = $file1//tbody/row/entry[1]/p)]"

You'll need to check that carefully though, don't assume it's correct.




Michael Kay
http://www.saxonica.com/
Author, XSLT Programmer's Reference and XPath 2.0 Programmer's Reference
Reply By: ShaileshShinde Reply Date: 4/24/2008 8:27:13 AM
Hi MhKay,

I tried with the below one...
select="$term.override[not(entry[1]/p[.= $file1//tbody/row/entry[1]/p])]"

it still outputs all the rows present in file2.

--
Shailesh



Reply By: ShaileshShinde Reply Date: 4/24/2008 8:52:24 AM
Hi MhKay,

Now getting the required output with below changes...
i have added apply templates after for-each..before closing </tbody>
 <!-- append unmatched rows -->
            <xsl:apply-templates select="$term.override[not(entry[1]/p[.=$r1])]"/>

and required output is appears.

thanks,
Shailesh


Go to topic 70802

Return to index page 1