nested xsl:for-each with document function

Discussion in 'XML' started by Cozmo, Sep 10, 2009.

  1. Cozmo

    Cozmo Guest

    Hello,

    I want to do a nested xsl:for-each with the document function.

    Here is a code snippet but it is not working:

    <xsl:variable name="cc" select="lower-case(../code-2)"/>
    <xsl:variable name="names_DA" select="document('export.xml')/
    translation/record[iso.code2=$cc]"/>
    <xsl:variable name="lgs" select="lg.vers"/>
    <xsl:for-each select="$names_DA">
    <xsl:for-each select="$lgs">
    <xsl:choose>
    <xsl:when test="@lg=$names_DA/source.lang"/>
    <xsl:eek:therwise>
    <xsl:element name="lg.vers">
    <xsl:attribute name="lg"><xsl:value-of select="$names_DA/
    source.lang"/></xsl:attribute>
    <xsl:value-of select="$names_DA/short.name"/>
    </xsl:element>
    </xsl:eek:therwise>
    </xsl:choose>
    </xsl:for-each>
    </xsl:for-each>

    The problem I have is that I have to run through all entries of the
    external document (with restriction) and afterwards check the other
    restrictions in the second for-each. I want to check if the entries
    already exists and if not I have to add them out of the external
    docoument.

    if I use this one:
    <xsl:value-of select="$names_DA/short.name"/>
    I get entries but it returns the complete records and not only the
    current one of the for-each loop.

    Hope this explains the problem. Would be happy for any help!

    Thanks a lot.
    Cozmo
     
    Cozmo, Sep 10, 2009
    #1
    1. Advertising

  2. Cozmo wrote:
    > Hello,
    >
    > I want to do a nested xsl:for-each with the document function.
    >
    > Here is a code snippet but it is not working:
    >
    > <xsl:variable name="cc" select="lower-case(../code-2)"/>
    > <xsl:variable name="names_DA" select="document('export.xml')/
    > translation/record[iso.code2=$cc]"/>
    > <xsl:variable name="lgs" select="lg.vers"/>
    > <xsl:for-each select="$names_DA">
    > <xsl:for-each select="$lgs">
    > <xsl:choose>
    > <xsl:when test="@lg=$names_DA/source.lang"/>
    > <xsl:eek:therwise>
    > <xsl:element name="lg.vers">
    > <xsl:attribute name="lg"><xsl:value-of select="$names_DA/
    > source.lang"/></xsl:attribute>
    > <xsl:value-of select="$names_DA/short.name"/>
    > </xsl:element>
    > </xsl:eek:therwise>
    > </xsl:choose>
    > </xsl:for-each>
    > </xsl:for-each>
    >
    > The problem I have is that I have to run through all entries of the
    > external document (with restriction) and afterwards check the other
    > restrictions in the second for-each. I want to check if the entries
    > already exists and if not I have to add them out of the external
    > docoument.
    >
    > if I use this one:
    > <xsl:value-of select="$names_DA/short.name"/>
    > I get entries but it returns the complete records and not only the
    > current one of the for-each loop.
    >
    > Hope this explains the problem. Would be happy for any help!


    So you have two XML input documents and want to process them and compare
    nodes. Please show us relevant sample of the two documents and explain
    the XML output you want the stylesheet to create for those two samples.

    --

    Martin Honnen
    http://msmvps.com/blogs/martin_honnen/
     
    Martin Honnen, Sep 10, 2009
    #2
    1. Advertising

  3. Cozmo

    Cozmo Guest

    On Sep 10, 1:54 pm, Martin Honnen <> wrote:
    > Cozmo wrote:
    > > Hello,

    >
    > > I want to do a nested xsl:for-each with the document function.

    >
    > > Here is a code snippet but it is not working:

    >
    > > <xsl:variable name="cc" select="lower-case(../code-2)"/>
    > >         <xsl:variable name="names_DA" select="document('export.xml')/
    > > translation/record[iso.code2=$cc]"/>
    > >    <xsl:variable name="lgs" select="lg.vers"/>
    > >    <xsl:for-each select="$names_DA">
    > >            <xsl:for-each select="$lgs">
    > >                    <xsl:choose>
    > >                            <xsl:when test="@lg=$names_DA/source.lang"/>
    > >                            <xsl:eek:therwise>
    > >                                    <xsl:element name="lg.vers">
    > >                                            <xsl:attribute name="lg"><xsl:value-of select="$names_DA/
    > > source.lang"/></xsl:attribute>
    > >                                            <xsl:value-of select="$names_DA/short.name"/>
    > >                                    </xsl:element>
    > >                            </xsl:eek:therwise>
    > >                    </xsl:choose>
    > >            </xsl:for-each>
    > >    </xsl:for-each>

    >
    > > The problem I have is that I have to run through all entries of the
    > > external document (with restriction) and afterwards check the other
    > > restrictions in the second for-each. I want to check if the entries
    > > already exists and if not I have to add them out of the external
    > > docoument.

    >
    > > if I use this one:
    > > <xsl:value-of select="$names_DA/short.name"/>
    > > I get entries but it returns the complete records and not only the
    > > current one of the for-each loop.

    >
    > > Hope this explains the problem. Would be happy for any help!

    >
    > So you have two XML input documents and want to process them and compare
    > nodes. Please show us relevant sample of the two documents and explain
    > the XML output you want the stylesheet to create for those two samples.
    >
    > --
    >
    >         Martin Honnen
    >        http://msmvps.com/blogs/martin_honnen/


    Hello,

    No I have one input document and want to transform it via saxon. But I
    need data from a second one so I use the document function. (merge the
    information)

    First input file:

    <record>
    <c2>AD</c2>
    <c3>AS</c3>
    <cn>002</cn>
    <short.name>
    <lg.vers lg="ss">text</lg.vers>
    <lg.vers lg="tt">text</lg.vers>
    <lg.vers lg="ts">text</lg.vers>
    .....


    the file which I import via the document function:

    <record>
    <short.name>test</short.name>
    <long.name>text</long.name>
    <iso.code2>AD</iso.code2>
    <source.lang>bg</source.lang>
    </record>
    <record>
    <short.name>test</short.name>
    <long.name>text</long.name>
    <iso.code2>AD</iso.code2>
    <source.lang>tt</source.lang>
    </record>
    <record>
    <short.name>test</short.name>
    <long.name>text</long.name>
    <iso.code2>DZ</iso.code2>
    <source.lang>bg</source.lang>
    </record>

    In the second file are additional information which I want to Add as a
    node. Example:
    <lg.vers lg="bg">test</lg.vers> should be added.

    As you can see first restriction c2 = iso.code2.
    Second restriction add elemnt only if source.lang doesnt exist list.
    ( So, @lg = tt shouldn't be added)

    Someting like that "c2 = iso.code2 and sourcelang != @lg"

    But as I have to loop through all these items its difficult.

    Any idea? Hope this explains the problem.

    Thanks for helping.

    Greets,
    Cozmo
     
    Cozmo, Sep 10, 2009
    #3
  4. Cozmo wrote:

    > No I have one input document and want to transform it via saxon. But I
    > need data from a second one so I use the document function. (merge the
    > information)
    >
    > First input file:
    >
    > <record>
    > <c2>AD</c2>
    > <c3>AS</c3>
    > <cn>002</cn>
    > <short.name>
    > <lg.vers lg="ss">text</lg.vers>
    > <lg.vers lg="tt">text</lg.vers>
    > <lg.vers lg="ts">text</lg.vers>
    > ....
    >
    >
    > the file which I import via the document function:
    >
    > <record>
    > <short.name>test</short.name>
    > <long.name>text</long.name>
    > <iso.code2>AD</iso.code2>
    > <source.lang>bg</source.lang>
    > </record>
    > <record>
    > <short.name>test</short.name>
    > <long.name>text</long.name>
    > <iso.code2>AD</iso.code2>
    > <source.lang>tt</source.lang>
    > </record>
    > <record>
    > <short.name>test</short.name>
    > <long.name>text</long.name>
    > <iso.code2>DZ</iso.code2>
    > <source.lang>bg</source.lang>
    > </record>
    >
    > In the second file are additional information which I want to Add as a
    > node. Example:
    > <lg.vers lg="bg">test</lg.vers> should be added.
    >
    > As you can see first restriction c2 = iso.code2.
    > Second restriction add elemnt only if source.lang doesnt exist list.
    > ( So, @lg = tt shouldn't be added)


    Assuming the primary input is

    <root>
    <record>
    <c2>AD</c2>
    <c3>AS</c3>
    <cn>002</cn>
    <short.name>
    <lg.vers lg="ss">text</lg.vers>
    <lg.vers lg="tt">text</lg.vers>
    <lg.vers lg="ts">text</lg.vers>
    </short.name>
    </record>
    </root>

    and the second XML document is

    <root>
    <record>
    <short.name>test</short.name>
    <long.name>text</long.name>
    <iso.code2>AD</iso.code2>
    <source.lang>bg</source.lang>
    </record>
    <record>
    <short.name>test</short.name>
    <long.name>text</long.name>
    <iso.code2>AD</iso.code2>
    <source.lang>tt</source.lang>
    </record>
    <record>
    <short.name>test</short.name>
    <long.name>text</long.name>
    <iso.code2>DZ</iso.code2>
    <source.lang>bg</source.lang>
    </record>
    </root>

    then this stylesheet copies everything from the primary input document
    and in the short.name element of each record elements adds new lg.vers
    elements:

    <xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">

    <xsl:strip-space elements="*"/>
    <xsl:eek:utput indent="yes"/>

    <xsl:param name="sd" select="'test2009091002.xml'"/>
    <xsl:variable name="srs" select="document($sd)/root/record"/>

    <xsl:template match="@* | node()">
    <xsl:copy>
    <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
    </xsl:template>

    <xsl:template match="short.name">
    <xsl:copy>
    <xsl:apply-templates select="@* | node()"/>
    <xsl:apply-templates select="$srs[iso.code2 = current()/../c2 and
    not(source.lang = current()/lg.vers/@lg)]" mode="new"/>
    </xsl:copy>
    </xsl:template>

    <xsl:template match="record" mode="new">
    <lg.vers lg="{source.lang}"><xsl:value-of
    select="short.name"/></lg.vers>
    </xsl:template>

    </xsl:stylesheet>

    creates the output

    <root>
    <record>
    <c2>AD</c2>
    <c3>AS</c3>
    <cn>002</cn>
    <short.name>
    <lg.vers lg="ss">text</lg.vers>
    <lg.vers lg="tt">text</lg.vers>
    <lg.vers lg="ts">text</lg.vers>
    <lg.vers lg="bg">test</lg.vers>
    </short.name>
    </record>
    </root>

    --

    Martin Honnen
    http://msmvps.com/blogs/martin_honnen/
     
    Martin Honnen, Sep 10, 2009
    #4
  5. Cozmo

    Cozmo Guest

    On Sep 10, 3:01 pm, Martin Honnen <> wrote:
    > Cozmo wrote:
    > > No I have one input document and want to transform it via saxon. But I
    > > need data from a second one so I use the document function. (merge the
    > > information)

    >
    > > First input file:

    >
    > >    <record>
    > >            <c2>AD</c2>
    > >            <c3>AS</c3>
    > >            <cn>002</cn>
    > >            <short.name>
    > >                    <lg.vers lg="ss">text</lg.vers>
    > >                    <lg.vers lg="tt">text</lg.vers>
    > >                         <lg.vers lg="ts">text</lg.vers>
    > > ....

    >
    > > the file which I import via the document function:

    >
    > >    <record>
    > >            <short.name>test</short.name>
    > >            <long.name>text</long.name>
    > >            <iso.code2>AD</iso.code2>
    > >            <source.lang>bg</source.lang>
    > >    </record>
    > >    <record>
    > >            <short.name>test</short.name>
    > >            <long.name>text</long.name>
    > >            <iso.code2>AD</iso.code2>
    > >            <source.lang>tt</source.lang>
    > >    </record>
    > >    <record>
    > >            <short.name>test</short.name>
    > >            <long.name>text</long.name>
    > >            <iso.code2>DZ</iso.code2>
    > >            <source.lang>bg</source.lang>
    > >    </record>

    >
    > > In the second file are additional information which I want to Add as a
    > > node. Example:
    > >  <lg.vers lg="bg">test</lg.vers>  should be added.

    >
    > > As you can see first restriction c2 = iso.code2.
    > > Second restriction add elemnt only if source.lang doesnt exist list.
    > > ( So, @lg = tt shouldn't be added)

    >
    > Assuming the primary input is
    >
    > <root>
    >         <record>
    >                 <c2>AD</c2>
    >                 <c3>AS</c3>
    >                 <cn>002</cn>
    >                 <short.name>
    >                         <lg.vers lg="ss">text</lg.vers>
    >                         <lg.vers lg="tt">text</lg.vers>
    >                          <lg.vers lg="ts">text</lg.vers>
    >                  </short.name>
    >          </record>
    > </root>
    >
    > and the second XML document is
    >
    > <root>
    >         <record>
    >                 <short.name>test</short.name>
    >                 <long.name>text</long.name>
    >                 <iso.code2>AD</iso.code2>
    >                 <source.lang>bg</source.lang>
    >         </record>
    >         <record>
    >                 <short.name>test</short.name>
    >                 <long.name>text</long.name>
    >                 <iso.code2>AD</iso.code2>
    >                 <source.lang>tt</source.lang>
    >         </record>
    >         <record>
    >                 <short.name>test</short.name>
    >                 <long.name>text</long.name>
    >                 <iso.code2>DZ</iso.code2>
    >                 <source.lang>bg</source.lang>
    >         </record>
    > </root>
    >
    > then this stylesheet copies everything from the primary input document
    > and in the short.name element of each record elements adds new lg.vers
    > elements:
    >
    > <xsl:stylesheet
    >    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    >    version="1.0">
    >
    >    <xsl:strip-space elements="*"/>
    >    <xsl:eek:utput indent="yes"/>
    >
    >    <xsl:param name="sd" select="'test2009091002.xml'"/>
    >    <xsl:variable name="srs" select="document($sd)/root/record"/>
    >
    >    <xsl:template match="@* | node()">
    >      <xsl:copy>
    >        <xsl:apply-templates select="@* | node()"/>
    >      </xsl:copy>
    >    </xsl:template>
    >
    >    <xsl:template match="short.name">
    >      <xsl:copy>
    >        <xsl:apply-templates select="@* | node()"/>
    >        <xsl:apply-templates select="$srs[iso.code2 = current()/../c2 and
    > not(source.lang = current()/lg.vers/@lg)]" mode="new"/>
    >      </xsl:copy>
    >    </xsl:template>
    >
    >    <xsl:template match="record" mode="new">
    >      <lg.vers lg="{source.lang}"><xsl:value-of
    > select="short.name"/></lg.vers>
    >    </xsl:template>
    >
    > </xsl:stylesheet>
    >
    > creates the output
    >
    > <root>
    >     <record>
    >        <c2>AD</c2>
    >        <c3>AS</c3>
    >        <cn>002</cn>
    >        <short.name>
    >           <lg.vers lg="ss">text</lg.vers>
    >           <lg.vers lg="tt">text</lg.vers>
    >           <lg.vers lg="ts">text</lg.vers>
    >           <lg.vers lg="bg">test</lg.vers>
    >        </short.name>
    >     </record>
    > </root>
    >
    > --
    >
    >         Martin Honnen
    >        http://msmvps.com/blogs/martin_honnen/


    Amazing it is working. Wonderful you helped a lot! Quite happy
    know :)

    Thanks a lot!!!!
     
    Cozmo, Sep 10, 2009
    #5
  6. Cozmo

    Dinis

    Joined:
    Mar 20, 2010
    Messages:
    1
    hello, and if I have an xml document with variables, for example like this ...

    <root>
    > * * <record>
    > * * * * <C2> AD = 1 </ c2>
    > * * * * <c3> AS = 2 </ c3>
    > * * </ Record>
    > </ Root>

    is possible with the XSLT document() function to take the values 1 and 2?

    thanks
     
    Dinis, Mar 20, 2010
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Sparko
    Replies:
    0
    Views:
    411
    Sparko
    Jul 9, 2004
  2. Tjerk Wolterink

    xsl:for-each for each 3 elements problem

    Tjerk Wolterink, Nov 3, 2004, in forum: XML
    Replies:
    3
    Views:
    432
    Tjerk Wolterink
    Nov 3, 2004
  3. Replies:
    1
    Views:
    3,623
    A. Bolmarcich
    May 27, 2005
  4. =?iso-8859-1?q?Jean-Fran=E7ois_Michaud?=

    Help with XSL/XSL:FO for producing revision indicator bar in document.

    =?iso-8859-1?q?Jean-Fran=E7ois_Michaud?=, Apr 28, 2006, in forum: XML
    Replies:
    6
    Views:
    577
    =?iso-8859-1?q?Jean-Fran=E7ois_Michaud?=
    May 3, 2006
  5. Richard A. DeVenezia

    Nested function X vs. nested varX = function

    Richard A. DeVenezia, Sep 8, 2003, in forum: Javascript
    Replies:
    1
    Views:
    133
    Code Ronin
    Sep 9, 2003
Loading...

Share This Page