Re: [xsl] Follow path in source-xml according to another source-document

Subject: Re: [xsl] Follow path in source-xml according to another source-document
From: "Mukul Gandhi" <gandhi.mukul@xxxxxxxxx>
Date: Fri, 23 Nov 2007 09:23:06 +0530
Please try the following stylesheet:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
                       version="1.0">
	
  <xsl:output method="text" />

  <xsl:variable name="largeDoc" select="document('large.xml')" />

  <!-- matches the leaf element -->
  <xsl:template match="*[not(node())]">
    <xsl:variable name="result">
      <xsl:call-template name="getText">
        <xsl:with-param name="largeDoc" select="$largeDoc/*" />
        <xsl:with-param name="elem" select="." />
      </xsl:call-template>
    </xsl:variable>
    <xsl:value-of select="normalize-space($result)" /><xsl:text>&#xa;</xsl:text>
  </xsl:template>

  <xsl:template match="text()" />

  <xsl:template name="getText">
    <xsl:param name="largeDoc" />
    <xsl:param name="elem" />

    <xsl:choose>
      <xsl:when test="(local-name($largeDoc) = local-name($elem)) and
($largeDoc/@id = $elem/@id)">
        <xsl:value-of select="$largeDoc" />
      </xsl:when>
      <xsl:otherwise>
        <xsl:for-each select="$largeDoc/*">
          <xsl:call-template name="getText">
	     <xsl:with-param name="largeDoc" select="." />
	     <xsl:with-param name="elem" select="$elem" />
          </xsl:call-template>
        </xsl:for-each>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

</xsl:stylesheet>

PS: This stylesheet is applied to the "light" input XML. And the other
XML is named as, large.xml.
There are some approximations for the input structure, and also some
redundant processing.

On Nov 22, 2007 10:27 PM,  <christoph.naber@xxxxxxxxxxx> wrote:
> Hello list,
>
> I want to follow a path in a given source-document, which is a
> "light"-version of another source document.
>
> The used processor is xsltproc, but the stylesheet is intended to run on
> Xalan so I have to use XSLT 1.0. The input-file-size will be up to 5 MB.
>
> Example "light" input XML
> <root>
>        <elem1 id="one">
>                <elem2 id="two">
>                        <elem4 id="three_three" />
>                </elem2>
>                <elem3 id="six">
>                        <elem5 id="seven" />
>                </elem3>
>        </elem1>
> </root>
>
> Example "large" input XML
> <root>
>        <elem1 id="one">
>                <elem2 id="two">
>                        <elem4 id="three_one" />
>                        <elem4 id="three_two" />
>                        <elem4 id="three_three">
>                                Here is the data of three_three
>                        </elem4>
>                        <elem4 id="three_four" />
>                </elem2>
>                <elem3 id="four">
>                        <elem5 id="five" />
>                </elem3>
>                <elem3 id="six">
>                        <elem5 id="seven" >
>                                Here is the data of seven
>                        </elem5>
>                </elem3>
>                <elem3 id="eight">
>                        <elem5 id="nine" />
>                </elem3>
>        </elem1>
> </root>
>
> Desired output:
> Here is the data of three_three
> Here is the data of seven
>
> This is the stylesheet that I managed to write so far. But I have no idea
> if this is the XSL-way to perform such a task.
>
> <xsl:stylesheet version="1.0"
>        xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
>        xmlns:exsl="http://exslt.org/common";>
>        <xsl:output method="xml" indent="yes"/>
>
>        <xsl:param name="lightdoc" select="string('light.xml')" />
>
>        <xsl:template match="/" >
>                <xsl:apply-templates select="root" >
>                        <xsl:with-param name="light"
> select="document($lightdoc)/root" />
>                </xsl:apply-templates>
>        </xsl:template>
>
>
>        <xsl:template match="node()" >
>                <xsl:param name="light" />
>                <xsl:variable name="large" select="current()" />
>
>                <xsl:choose>
>                        <!-- We dont want to match textnodes or
> processing-instructions -->
>                        <xsl:when test="count($light/*) > 0" >
>                                <xsl:for-each select="$light/*">
>                                        <!-- not sure if I have to use
> node-set here -->
>                                        <xsl:apply-templates
> select="exsl:node-set($large)/node()[@id = current()/@id]" >
>                                                <xsl:with-param
> name="light" select="current()" />
>                                        </xsl:apply-templates>
>                                </xsl:for-each>
>                        </xsl:when>
>                        <xsl:otherwise>
>                                <xsl:value-of select="$large/text()" />
>                        </xsl:otherwise>
>                </xsl:choose>
>
>        </xsl:template>
>
> </xsl:stylesheet>
>
> Any insight, eg. search items would be appreciated.
>
> Greetings
> Christoph Naber


-- 
Regards,
Mukul Gandhi

Current Thread