如何在XSLT中搜索特定的兄弟姐妹?

时间:2014-04-07 13:18:37

标签: xml xslt xpath nodes siblings

我有像

这样的节点
<Level1 id="11">
  <Level2 id="1111">
    <Level3 type="UserID" id="111111">12345
    </Level3>
    <Level3 type="UserID" id="111112">23456
    </Level3>
  </Level2>
  <Level2 id="1112">
    <Level3 type="Username" id="111211">John
    </Level3>
    <Level3 type="Username" id="111212">Paul
    </Level3>
  </Level2>
  <Level2 id="1113">
    <Level3 type="Street" id="111311">Westminster Rd.
    </Level3>
    <Level3 type="Street" id="111312">Long Rd.
    </Level3>
 </Level2>
</Level1>

并希望获得一个类似

的列表
<personlist>
  <person>
    <name>12345</name>
    <name>John</name>
    <name>Westminster Rd.</name>
  </person>
  <person>
    <name>23456</name>
    <name>Paul</name>
    <name>Long Rd.</name>
  </person>
</personlist>

UserID的第一个节点始终对应Name和Street的第一个节点,ID的第二个节点对应于名称和街道的第二个节点,依此类推。

所以我知道我可以进入类型为&#34; UserID&#34;的每个Level3节点。并得到这个位置。 但不知怎的,这不起作用。 这是我的代码:

<xsl:for-each select="//Level3[@type='UserID']">
  <xsl:variable name="pos">
    <xsl:value-of select="position()"/>
  </xsl:variable>                
  <xsl:value-of select="..//Level3[$pos]"/>
</xsl:for-each>

但不知何故,我只得到了12345 ......

2 个答案:

答案 0 :(得分:0)

您正在使用的XML是针对此类结果而奇怪地构建的,但您当前的XPath正在做的只是让<Level3>个节点具有type = UserID,然后获取它们的位置和使用该索引冗余地获取相同的数据。由于您的定位XPath中只有2个节点,因此您只会获取这些索引的结果,这就是您每次都看到12345的原因。

尝试使用类似<xsl:for-each select="//Level3">的内容,它会为您提供您尝试检索的所有Level3数据的列表,然后通过xslt格式化。由于您的ID不符合每行,因此您必须按位置行事,并希望您认为它们对应的假设是正确的。

答案 1 :(得分:0)

使用表达式

..//Level3[$pos]

你只在树的一层到Level2元素。你应该上升到Level1元素的两个级别:

../../Level2/Level3[$pos]

另一个问题是你计算Level3元素位置的方式是错误的。表达式

position()

返回您正在迭代的节点集中的位置,而不是父元素内的位置。你需要这样的东西:

count(preceding-sibling::Level3) + 1

然后,您应该确保在select的{​​{1}}属性中评估此表达式。如果您使用xsl:variable,结果将是一个字符串,在您稍后将其用作索引时,它将无法达到预期效果。

总结一下,以下内容应该有效:

xsl:value-of