xml - How to parse references in XSLT -


i have code this

<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> 

and want write xslt code, print book name, auther name.

how parse reference auther name using xslt?

<xsl:for-each select="/library/books/book">     book name: <xsl:value-of select="./name"/>     auther name: ????? </xsl:for-each> 

i in 2 phases; first phase add path author elements. second phase use added path produce desired output.

this done in single xslt (2.0) putting new input path added in variable, cause memory issues larger documents.

xml input (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> 

first xslt (pass1.xsl)

this add attribute path author elements.

<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 output (temp.xml)

notice @path has been added.

<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> 

second 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,'&#xa;')"/>         <xsl:value-of select="concat('author name: ',         /*/authors/author[@path=current()/author-ref]/name,'&#xa;')"/>     </xsl:template>      <xsl:template match="text()"/>  </xsl:stylesheet> 

final output

book name: book 1 author name: sandra johns book name: book 2 author name: john smith 

Comments