Combining two xml files based on unique nodes using XSL
I have two files. There is some overlap in data but I want to pull specific info from file2 and add to file1.
File1.xml looks as such:
<content>
<book>
<id>111aaa</id>
<author>John Doe</author>
<title>This is a book</title>
<price>$10.00</price>
</book>
<book>
<id>111bbb</id>
<author>Jane Doe</author>
<title>This is another book</title>
<price>$20.00</price>
</book>
</content>
File2.xml looks as such:
<content>
<book>
<id>111aaa</id>
<author>John Doe</author>
<year>2011</year>
<pages>100</pages>
</book>
<book>
<id>111bbb</id>
<author>Jane Doe</author>
<year>2010</year>
<pages>200</pages>
</book>
</content>
I want to pull the year and pages tags from file2 and add it to file1 and have an outputted file3.xml file that looks as such:
<content>
<book>
<id>111aaa</id>
<author>John Doe</author>
<title>This is a book</title>
<year>2011</year>
<pages>100</pages>
<price>$10.00</price>
</book>
<book>
<id>111bbb</id>
<author>Jane Doe</author>
<title>This is a another book</title>
<year>2010</year>
<pages>200</pages>
<price>$20.00</price>
</book>
</content>
I am using a command line to run xsltproc:
xsltproc transform.xsl file1.xml > file3.xml
I have the following chunk in my xsl but it is only combining the data of the first book. Do you know how to write the xsl to go through each book?
<xsl:choose>
<xsl:when test="document('file2.xml')/content/book/id = id">
<xsl:for-each select="document('file2.xml')/content/book">
<xsl:element name="pages">
<xsl:value-of select="document('file2.xml')/content/book/pages"/>
</xsl:element>
<xsl:element name="year">
<xsl:value-of select="document('file2.xml')/content/book/year"/>
开发者_StackOverflow中文版 </xsl:element>
</xsl:for-each>
</xsl:when>
<xsl:otherwise></xsl:otherwise>
</xsl:choose>
You're looking for something along these lines, I guess. Fixing syntax left up to you.
<xsl:for-each select="book">
<xsl:copy>
<xsl:apply-templates/>
<xsl:variable name="id" select="string(id)"/>
<xsl:for-each select="document('file2.xml')/content/book[string(id)=$id]/*">
<xsl:apply-templates/><!-- Add in a choose here if you just want to pick out certain fields, or in the for-each above -->
</xsl:for-each>
</xsl:copy>
</xsl:for-each>
Cross-references ask for using a key:
<xsl:key name="k1" match="book" use="id"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="book">
<xsl:variable name="id" select="id"/>
<xsl:apply-templates select="@* | id | author"/>
<xsl:for-each select="document('file2.xml')">
<xsl:apply-templates select="key('k1', $id)/year | key('k1', $id)/pages"/>
</xsl:for-each>
<xsl:apply-templates select="price"/>
</xsl:template>
精彩评论