XSLT计算具有相同名称和XML的XML节点访问第N个元素

时间:2014-04-17 16:53:05

标签: xml xslt

以下是我的示例xml:

<?xml version="1.0" encoding="UTF-8"?>
<root xmlns:something-well-formed"> 
  <child1 attr1="a" attr2="b"> 
     <child1 attr1="a" attr2="b"/>
  </child1>
  <child3/>
  <child1 attr1="a" attr2="b"> 
     <child2 attr1="a" attr2="b"/> 
  </child1>
</root>

问题1:你如何计算child1节点的数量? 下面我传递字符串&#34; child1&#34;到我的&#34;元素&#34;参数,但实现这个的正确xslt语法是什么?

这是我的示例XSLT

<xsl:param name="element"/>
   <xsl:template match="@*|node()">
      <root>
        <name><xsl:value-of select="count(/root/*[local-name()='$element'])"/> 
         </name>
      </root>

问题2:给出相同的xml示例,如何访问第N个child1元素?我想将其属性设置为指定值,但同样,再次哄骗语法。这是我的示例尝试:

<xsl:param name="element" />
<xsl:param name="attributes" />
<xsl:param name="nodeNumber" />


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

<xsl:template match="*[local-name(.)=$element][count(preceding::*[local-name()='$element'] | ancestor::*[local-name()='$element'])=number($nodeNumber)]">
    <xsl:copy>
        <xsl:apply-templates select="@*" />

        <!-- Splits into separate key/value pairs elements -->
        <xsl:variable name="attributesSeq" select="tokenize($attributes, ';')" />
        <xsl:for-each select="$attributesSeq">
            <xsl:variable name="attributesSeq" select="tokenize(., ',')" />

            <xsl:variable name="key"
                select="replace($attributesSeq[1], '&quot;', '')" />
            <xsl:variable name="value"
                select="replace($attributesSeq[2], '&quot;', '')" />

            <xsl:attribute name="{$key}">
                <xsl:value-of select="$value" />
            </xsl:attribute>
        </xsl:for-each>
        <xsl:apply-templates select="node()[$nodeNumber]" /> 
    </xsl:copy>
</xsl:template>

感谢您的帮助!

2 个答案:

答案 0 :(得分:2)

计算出现在文档中任何位置的给定元素的出现次数:

count(//*[local-name()=$element])

选择第n次出现:

(//*[local-name()=$element])[$n]

一个完整的例子:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:param name="element" />
    <xsl:variable name="n" select="2" />
    <xsl:template match="/">
        <xsl:value-of select="count(//*[local-name()=$element])" />
        <xsl:apply-templates select="(//*[local-name()=$element])[$n]" />
    </xsl:template>
    <xsl:template match="child1">
        [<xsl:value-of select="@attr1" />]
    </xsl:template>
</xsl:stylesheet>

请注意,您无法在XSLT 1.0中引用匹配模式中的参数,这就是我选择选择参数化名称的元素但被迫在匹配中使用文字名称的原因。

答案 1 :(得分:0)

不管层次结构如何,Xpath表达式//child1都不会为您提供所有这些表达式的节点集吗? //child1[9]给你一个特定索引位置的那个?我可能会误解你的问题。