我会分两个阶段进行;第一阶段是添加Author
元素的路径。第二阶段使用添加的路径来产生所需的输出。
这可以在单个 XSLT (2.0) 中通过将新输入和路径添加到变量中来完成,但这会导致较大文档的内存问题。
XML 输入(input.xml)
<Library>
<Books>
<Book>
<ISBN>123</ISBN>
<Name>Book 1</Name>
<Author-Ref>/Library/Authors/Author[2]</Author-Ref>
</Book>
<Book>
<ISBN>425</ISBN>
<Name>Book 2</Name>
<Author-Ref>/Library/Authors/Author[1]</Author-Ref>
</Book>
</Books>
<Authors>
<Author>
<Name>John smith</Name>
<Nationality>American</Nationality>
<BirthDate>08051977</BirthDate>
</Author>
<Author>
<Name>Sandra Johns</Name>
<Nationality>American</Nationality>
<BirthDate>03091981</BirthDate>
</Author>
</Authors>
</Library>
第一个 XSLT (pass1.xsl)
这会将属性添加path
到Author
元素中。
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:if test="self::Author">
<xsl:attribute name="path">
<xsl:for-each select="ancestor-or-self::*">
<xsl:value-of select="concat('/',local-name())"/>
<xsl:if test="(preceding-sibling::*|following-sibling::*)[local-name()=local-name(current())]">
<xsl:value-of select="concat('[',count(preceding-sibling::*[local-name()=local-name(current())])+1,']')"/>
</xsl:if>
</xsl:for-each>
</xsl:attribute>
</xsl:if>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
XML 输出(temp.xml)
@path
已添加通知。
<Library>
<Books>
<Book>
<ISBN>123</ISBN>
<Name>Book 1</Name>
<Author-Ref>/Library/Authors/Author[2]</Author-Ref>
</Book>
<Book>
<ISBN>425</ISBN>
<Name>Book 2</Name>
<Author-Ref>/Library/Authors/Author[1]</Author-Ref>
</Book>
</Books>
<Authors>
<Author path="/Library/Authors/Author[1]">
<Name>John smith</Name>
<Nationality>American</Nationality>
<BirthDate>08051977</BirthDate>
</Author>
<Author path="/Library/Authors/Author[2]">
<Name>Sandra Johns</Name>
<Nationality>American</Nationality>
<BirthDate>03091981</BirthDate>
</Author>
</Authors>
</Library>
第二个 XSLT (pass2.xsl)
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/*/Books/Book">
<xsl:value-of select="concat('Book Name: ',Name,'
')"/>
<xsl:value-of select="concat('Author Name: ',
/*/Authors/Author[@path=current()/Author-Ref]/Name,'
')"/>
</xsl:template>
<xsl:template match="text()"/>
</xsl:stylesheet>
最终输出
Book Name: Book 1
Author Name: Sandra Johns
Book Name: Book 2
Author Name: John smith