Exclude first child with XSL-T

2019-04-21 11:25发布

问题:

What I'm trying to do is fairly simple, but I can't find the way to. I just want to iterate over the children of a node excluding the first child.

For instance, in this XML snippet, I would want all the <bar> elements, except the first one:

<foo>
    <Bar>Example</Bar>
    <Bar>This is an example</Bar>
    <Bar>Another example</Bar>
    <Bar>Bar</Bar>
</foo>

There is no common attribute by which I can filter (like an id tag or something similar).

Any suggestions?

回答1:

You can always use position together with xsl:when.

<xsl:when test="node[position() > 1]">
  <!-- Do my stuff -->
</xsl:when>


回答2:

/foo/Bar[position() > 1]

For example, in C#:

[Test]
public void PositionBasedXPathExample()
{
    string xml = @"<foo>
                     <Bar>A</Bar>
                     <Bar>B</Bar>
                     <Bar>C</Bar>
                   </foo>";

    XDocument xDocument = XDocument.Parse(xml);
    var bars = xDocument.XPathSelectElements("/foo/Bar[position() > 1]")
        .Select(element => element.Value);

    Assert.That(bars, Is.EquivalentTo(new[] { "B", "C" }));
}


回答3:

/foo/bar[position() > 1]

selects all bar elements with the exception of the first, that are children of the top element, which is foo.

(//bar)[position() >1]

selects all bar elements in in any XML document, with the exception of the first bar element in this document.



回答4:

Using apply-templates:

<xsl:apply-templates select="foo/Bar[position() > 1]" />

or the same xpath for for-each:

<xsl:for-each select="foo/Bar[position() > 1]">
    …
</xsl:for-each>