Itay.B
Itay.B

Reputation: 4111

Xsl xml loop issue

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.

Upvotes: 1

Views: 131

Answers (3)

Emiliano Poggi
Emiliano Poggi

Reputation: 24816

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.

Upvotes: 1

Kirill Polishchuk
Kirill Polishchuk

Reputation: 56162

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>

Upvotes: 3

ColinE
ColinE

Reputation: 70142

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

Upvotes: 1

Related Questions