XSLT节点集之间的值不同

时间:2012-01-13 13:23:56

标签: xslt xpath node-set

再次讨论节点集中的不同节点(基于属性值)。 想象一下,你有以下结构:

<struct>
  <a>
    <x id="1">a_1</x>
    <x id="2">a_2</x>
    <x id="3">a_3</x>
  </a>
  <b inherits="a">
    <x id="2">b_2</x>
  </b>
</struct>

<struct/>可能包含多个元素,例如<b/>,它们会继承相同的<a/>。同时允许使用<a/>等多个元素。 <a/><b/>的顺序是任意的。继承是单层深度的。

问题:如何创建 XPath,为给定的<b/>选择以下节点集:

<x id="1">a_1</x>
<x id="2">b_2</x>
<x id="3">a_3</x>

请注意第二行的b_2值。

对此有何解决方案?

更新

resuting XPath应具有以下格式:b[(magic_xpath)[@id=2]='b_2'],其中magic_xpath<x/><a/> s中选择不同的<b/>

现实生活<struct/>可能如下所示:

<struct>
  <a>
    <x id="1">a_1</x>
    <x id="2">a_2</x>
    <x id="3">a_3</x>
  </a>
  <b inherits="a">
    <x id="2">I don't match resulting XPath</x>
  </b>
  <b inherits="a">
    <x id="2">b_2</x>
  </b>
</struct>

1 个答案:

答案 0 :(得分:1)

使用

  $vB/x
 |
  /*/*[name() = $vB/@inherits]
                /x[not(@id = $vB/x/@id)]

其中$vB被定义为b元素。

这将选择{{1}的所有b/x个元素和所有x个子元素(id属性不等于任何b/x/@id属性)的并集} {(struct/*的子项),其名称为struct的值。

或者,根据OP在评论中的要求 - 没有变量:

b/@inherits

完成基于XSLT的验证

  /*/b/x
 |
  /*/*[name() = /*/b/@inherits]
                /x[not(@id = /*/b/x/@id)]

将此转换应用于提供的(已更正为格式良好的)XML文档

<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:copy-of select=
     "/*/b/x
     |
      /*/*[name() = /*/b/@inherits]
                    /x[not(@id = /*/b/x/@id)]

   "/>
 </xsl:template>
</xsl:stylesheet>

评估单个XPath表达式并输出所选节点

<struct>
    <a>
        <x id="1">a_1</x>
        <x id="2">a_2</x>
        <x id="3">a_3</x>
    </a>
    <b inherits="a">
        <x id="2">b_2</x>
    </b>
</struct>