2

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

<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/>s 和s 的顺序<b/>是任意的。继承是单级深度的。

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

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

请注意b_2第二行的值。

有什么解决办法吗?

更新:

产生的 XPath 应具有以下形式:b[(magic_xpath)[@id=2]='b_2'],其中从s 和s 中magic_xpath选择不同的s。<x/><a/><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>
4

1 回答 1

1

使用

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

where$vB被定义为b元素。

这将选择名称为 的值的元素(的子级)的所有b/x元素和所有x子级(具有id不等于任何b/x/@id属性的属性)的并集。struct/*structb/@inherits

或者,按照 OP 在评论中的要求——不带变量:

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

完成基于 XSLT 的验证

<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>

当此转换应用于提供的(更正为格式正确的)XML 文档时

<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>

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

<x id="1">a_1</x>
<x id="3">a_3</x>
<x id="2">b_2</x>
于 2012-01-13T13:56:34.743 回答