Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/xpath/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在xpath中进行组捕获_Xpath - Fatal编程技术网

如何在xpath中进行组捕获

如何在xpath中进行组捕获,xpath,Xpath,我正在寻找xpath可以做的事情://foo[@n=“$1”]//bar[@n=“$2”] 它可以返回我$1和$2。或者至少将和 下面是更详细的信息,我有一个xml文档: <xml> <foo> <a n="1"> <b n="1"/> <b n="2"/> </a> </foo> <a n="2"> <b n="1"/> &

我正在寻找xpath可以做的事情:
//foo[@n=“$1”]//bar[@n=“$2”]
它可以返回我
$1
$2
。或者至少将

下面是更详细的信息,我有一个xml文档:

<xml>
  <foo>
    <a n="1">
      <b n="1"/>
      <b n="2"/>
    </a>
  </foo>
  <a n="2">
    <b n="1"/>
  </a>
  <a n="3">
    <b n="1"/>
    <foo>
      <b n="2"/>
    </foo>
    <b n="3"/>
  </a>
</xml>

我想根据
中的n属性生成一个字符串 所以我有xpath:
//a[@n]//b[@n]
然后,对于我得到的每个结果,我使用:
/@n
/祖先::a/@n
来获得我想要的信息

这很好,但我需要一些更智能的东西,因为我有很多这样的结构,需要自动生成xpath

因此,对于上面的示例,我正在寻找一些xpath,如:
//a[@n=“$1”]//b[@n=“$2”]
那就还给我:
`(1,1)、(1,2)、(2,1)、(3,1)、(3,2)、(3,3)

这里有一个XPath 1.0表达式,它选择所有想要的
n
属性:

//a[.//b]/@n | //a//b/@n
在没有优化的情况下,对上述表达式的求值至少会执行两次完整的XML文档遍历

此XPath 1.0表达式可能更有效

//*[self::a and .//b or self::b and ancestor::a]/@n
//*[self::a or self::b]/@n
for $a in //a[@n and .//b[@n]],
    $b in $a//b[@n]
  return
     concat('(', $a/@n, ',', $b/@n, ') ')
如果保证每个
a
都有一个
b
后代,则这两个表达式都可以简化

它们分别成为:

//a/@n | //a//b/@n
以及:

如果保证每个
a
都有一个后代
b
,每个
b
都有一个祖先
a
,则可以进一步简化:

//*[self::a and .//b or self::b and ancestor::a]/@n
//*[self::a or self::b]/@n
for $a in //a[@n and .//b[@n]],
    $b in $a//b[@n]
  return
     concat('(', $a/@n, ',', $b/@n, ') ')
在单个XPath 1.0表达式中不可能获得所有所需属性的字符串值。需要使用上述表达式之一获取所有属性,然后在每个选定属性上应用第二个XPath表达式:
string()

在Xpath 2.0中,可以使用单个表达式获取所需属性的所有字符串值——只需在每个表达式后面附加
/string(.)

例如,对于最简单的一个:

//(a|b)/@n/string(.)
更新

//*[self::a and .//b or self::b and ancestor::a]/@n
//*[self::a or self::b]/@n
for $a in //a[@n and .//b[@n]],
    $b in $a//b[@n]
  return
     concat('(', $a/@n, ',', $b/@n, ') ')
OP澄清了他的问题。现在我们知道他希望产生这样的结果:

使用单个XPath 1.0表达式无法生成所需的结果

以下XPath 2.0表达式生成所需的结果

//*[self::a and .//b or self::b and ancestor::a]/@n
//*[self::a or self::b]/@n
for $a in //a[@n and .//b[@n]],
    $b in $a//b[@n]
  return
     concat('(', $a/@n, ',', $b/@n, ') ')

请使用`字符转义内联代码(请参阅发布问题时弹出的帮助信息),否则浏览器会尝试将您的XML格式化为HTML,并且不可见。我已经编辑了它,但它正在等待审核。你能确认你想要的输出结构吗?乌特卡诺斯:是的,这是我想要的格式。谢谢你的帮助。迪米特里·诺瓦切夫:我的问题是我能做一些类似的事情吗:
//a[@n=“$1”]//b[@n=“$2”]
,这将返回a
中的所有
,并在没有任何其他查询的情况下给我$1$2。@user1508210:从你上面的评论中,不清楚确切的结果必须是什么。请编辑问题并提供准确的结果。到目前为止,我一直在努力猜测……:)@迪米特伦诺瓦切夫:很抱歉。我编辑了我的问题,这更清楚吗?谢谢你的重播,这比我现在拥有的要干净得多。但这并不能保证每个
内部都至少有一个
。它将返回类似这样的内容:
[1,1,2,2,1,3]
,很难说第一个1属于
,下一个12属于
。有什么能像regex group capture那样工作吗?@user1508210:我猜你想要这个结果——因为你没有向我们展示确切的想要的结果。请编辑问题,并提供此重要且当前缺失的信息。另外,您需要知道XPath只是XML文档的查询语言。因此,它不能改变XML文档的结构或创建新的XML文档/节点。如果您想要创建一个新文档,其结构适合您想要的结果,那么您需要使用另一种语言——最适合这种用途的语言是XSLT。