如何根据子元素的值获取节点的位置

时间:2013-04-05 13:37:12

标签: html xml xslt xpath xslt-2.0

在我的xml中,我希望特定的menuitems/menuitem节点位于其父节点下的不同任意位置(我不想要硬编码的位置选择器)。

是否可以获取menuitem节点的位置,该节点在其下的name元素中具有正确的值,这意味着menuitems/menuitem/name。简而言之:选择menuitem下具有正确name值的<one> <menuitems> <menuitem> <!-- I dont want this one --> <name> ... </name> </menuitem> <menuitem> <!-- I want this one at position 2 under <one> --> <name> ... <!-- Based one correct name value here --> </name> </menuitem> </menuitems> </one> <two> <menuitems> <menuitem> <!-- I want this one at position 1 under <two> --> <name> ... </name> </menuitem> </menuitems> </two>

menuitem

我可以很容易地找出menuitems下的name是否具有正确的 <xsl:value-of select="current()/menuitems/menuitem/name = 'OhYes'"></xsl:value-of> 值。像这样:

true

将返回menuitem。但是menuitem返回true的其他<xsl:if test="current()/menuitems/menuitem[1]/name = 'OhYes'"> .. </xsl:if> <xsl:if test="current()/menuitems/menuitem[2]/name = 'OhYes'"> .. </xsl:if> 中的哪个位置?在相同的父级和同一级别下选择。

我想避免这种情况:

{{1}}

2 个答案:

答案 0 :(得分:0)

您可以先使用getElementsByTagName分隔一个和两个容器。每个部分(一个,两个)尝试使用getElementsByTagName创建一个数组迭代所有名称,然后检查每个元素以查看名称是否正确。由于每个menuitem位置对应于每个标题下的名称位置(一,二),因此可以在每个匹配的名称节点上使用.parentNode访问器来返回menuitem节点,并使用迭代器的索引返回其位置。

例如,对于XML代码

    <one>
   <menuitems>
      <menuitem>  <!-- I dont want this one -->
         <name>
            the incorrect name
         </name>
      </menuitem>
   </menuitems>

   <menuitems>
      <menuitem> <!-- I want this one at position 2 -->
        <name>
           the correct name   <!-- Based one correct name value here --> 
        </name>
      </menuitem>
   </menuitems>
</one>
<two>
  <menuitems>
    <menuitem> <!-- I want this one at position 1 -->
       <name>
          the correct name
       </name>
     </menuitem>
   </menuitems>
</two>

以下代码警告当前容器(一,二)下名称节点(和父菜单项)的索引,这些容器在标记为“正确名称”的标记中包含正确的名称文本

names = new Array();

// Find the correct position for the menuitem under one
one = document.getElementsByTagName("one")[0];

names = one.getElementsByTagName("name");

for (var i=0; i<names.length; i++){
    if (names[i].innerHTML.search("the correct name") >= 0)
        alert("For one: Correct name found at name node index " + (i+1) + " and its parent menuitem is " + names[i].parentNode);

    // names[i].parentNode is the reference to the menuitem in one that contains the correct name
}   

// Find the correct position for the menuitem under two
two = document.getElementsByTagName("two")[0];

names = two.getElementsByTagName("name");

for (var i=0; i<names.length; i++){
    if (names[i].innerHTML.search("the correct name") >= 0)
        alert("For two: Correct name found at name node index " + (i+1) + " and its parent menuitem is " + names[i].parentNode);

    // names[i].parentNode is the reference to the menuitem in one that contains the correct name

}

我还在http://jsfiddle.net/nMN3j/1/创建了一个小提琴,这样你就可以尝试一下,看看它是如何工作的。

此代码将警告在容器“one”下,在第2位找到一个menuitem标签,该标签具有正确的名称子标签,但不在位置1,其名称子标签不正确。

对于容器“two”,代码将提示在位置1找到具有正确名称的menuitem。

希望这有帮助!

答案 1 :(得分:0)

使用此

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="/">
  <xsl:for-each select="/*/*/menuitems/menuitem[name='OhYes']">
   position: <xsl:text/>
    <xsl:value-of select="count(preceding-sibling::menuitem) +1"/>
  </xsl:for-each>
 </xsl:template>
</xsl:stylesheet>

**对以下XML文档应用此转换时:                                                                         ...                                                              - &GT;                 OhYes                                                                         - &GT;                 OhYes                           

产生了想要的正确结果

   position: 2
   position: 1