1

I have this xml with 3 nodes with the same name <person>. The problem is that 2 of them are under one parent node <people>, and the other one is under another <people> node, so when the Xsl loops it gets only the first 2.

Xml:

<data>
  <people>
    <person></person>
    <person></person>
  </people>
  <people>
    <person></person>
  </people>
</data>

Xsl loop:

<xsl:for-each select="//person">

Does someone know what I need to do to see all 3 of them?

Thanks.

3 Answers 3

3

Use can use this template with xsl:for-each:

<xsl:template match="data">
    <root>
        <xsl:for-each select="//person">
            <item>
                <xsl:value-of select="name(.)"/>
            </item>
        </xsl:for-each>
    </root>
</xsl:template>
Sign up to request clarification or add additional context in comments.

Comments

1

Rather than an xsl-foreach a better approach would be to use a template that matches the person nodes:

<xsl:template match="/">
  <!-- match any person element that is a descendant of the root -->
  <xsl:apply-templates select="//person"/>
</xsl:template>

<xsl:template match="person">
   <!-- transform the person element here -->
</xsl:template match="person">

3 Comments

Why is it "a better approach" than xsl-foreach ?
new approach for me. can you explain more please?
apply-templates selects a nodeset and searches for templates to apply. The template definition indicates how to transform an element that matches the "match" XPath. This allows you to write more loosely coupled templates. It is a bit like breaking up a complex method in C# into a number of separate methods. It promotes re-use, for example the template that transforms the person in the above example can be used in a number of different contexts. If it is hard-coded within a for-each loop, it cannot be re-used.
1

The XPath:

//person

selects all person elements no matter where they are in the XML input (see here).

The XSLT instruction:

<xsl:for-each select="//person">

Will iterate on all person elements selected by that XPath. Whatever context you are using this instruction, the transform should iterate on all three person elements. This is not true in situations like (given the sample input provided in your question):

<xsl:template match="/data/people[1]">
    <xsl:for-each select=".//person">
        <xsl:value-of select="name(.)"/>
    </xsl:for-each>
</xsl:template>

where you are explicitely selecting all person elements starting from a specific context. In such a case, and I think, in such a case only, you will iterate on the first two elements only.

Therefore there is something odd in your tests.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.