gpt4 book ai didi

php - 选择属性值为 self 或 descendant 但不是 "overruled"的元素(如 lang 属性)

转载 作者:搜寻专家 更新时间:2023-10-31 20:49:34 24 4
gpt4 key购买 nike

我试图模仿 lang 的解释类似于 HTML 或 xml:lang 的属性.

给定以下 XML block :

<xml lang="c">
c#0
<para>c#1</para>
<para>c#2</para>
<para lang="d">
d#0
<para>d#1</para>
<para lang="c">c#3</para>
<para lang="d">
d#2
<para>d#3</para>
<para lang="c">c#4</para>
</para>
<para lang="c">
c#5
<para>c#6</para>
</para>
</para>
</xml>

我在构建 XPath 1.0 表达式时遇到问题,该表达式返回所有属于特定语言的节点,比方说 c .节点匹配类似于 xpath lang()函数将匹配 xml:lang属性:

  1. 它具有属性 lang值为 c ( //*[@lang = "c"] )
  2. -或-
    1. 其中一个父级拥有 lang值为 c 的属性( //*[ancestor::*/@lang = "c"] )
    2. -AND- 节点本身没有lang完全没有属性
    3. -AND NOT- 如果它的任何父节点有 langc 以外定义的属性比 lang 的 parent 更“近”属性 c (2.1 被“否决”)。

与上述 XML 和 c 的示例匹配对于 lang会给出 7 个节点:c#0 到 c#6。

<xml lang="c"> c#0 ...              (direct match, lang="c")
<para>c#1</para> (parent has lang="c")
<para>c#2</para> (parent has lang="c")
<para lang="c">c#3</para> (direct match, lang="c")
<para lang="c">c#4</para> (direct match, lang="c")
<para lang="c"> c#5 ... (direct match, lang="c")
<para>c#6</para> (parent has lang="c", that parent is descending of
any other ancestor with lang="d")

我无法在 xpath 查询中对此进行描述。即使我在过去一年中使用 xpath 变得更好,这个真的让我失望。

无论我尝试什么,我都无法描述具有匹配谓词的祖先对具有不匹配谓词的祖先的否决性质。

给出的例子甚至只是问题的一半,因为不仅有完整的属性值匹配,还有像这样的起始匹配:

 starts-with(@lang, concat("c", "-"))

但我很高兴看到否决问题首先得到解决。我用 PHP ( Online Demo ) 测试:

<?php
header('Content-Type: text/plain');
$xml = <<<XML
<xml lang="c">
c#0
<para>c#1</para>
<para>c#2</para>
<para lang="d">
d#0
<para>d#1</para>
<para lang="c">c#3</para>
<para lang="d">
d#2
<para>d#3</para>
<para lang="c">c#4</para>
</para>
<para lang="c">
c#5
<para>c#6</para>
</para>
</para>
</xml>
XML;

$doc = new DOMDocument();
$doc->loadXML($xml);
$xp = new DOMXPath($doc);

$expression = '
//*[
ancestor-or-self::*/@lang = "c"
and (
not(ancestor-or-self::*/@lang != "c")
or (
count(ancestor-or-self::*[@lang != "c"])
< count(ancestor-or-self::*[@lang = "c"])
)
)
]';

$result = $xp->query($expression);
printResult($result);

function printResult($result)
{
global $xp;

if ($result) {
printf("Result (%d Nodes):\n", $result->length);
foreach ($result as $index => $node) {
$depth = $xp->evaluate('count(ancestor::*)', $node);
printf("#%d (%d): %s\n", $index, $depth, $node->ownerDocument->saveXML($node));
}
} else {
printf("No Result, query failed.\n");
}
}

最佳答案

使用:

//*[@lang='c'
or
not(@lang) and ancestor::*[@lang][1]/@lang = 'c'
]

这会选择 XML 文档中具有值为 "c"lang 属性或没有 lang 的任何元素属性及其第一个具有 lang 属性的祖先的 lang 属性的值为 "c"

一个更简单的等效 XPath 表达式:

//*[ancestor-or-self::*[@lang][1]/@lang='c']

这是使用 XPath Visualizer 执行的选择的快照:

enter image description here

关于php - 选择属性值为 self 或 descendant 但不是 "overruled"的元素(如 lang 属性),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9658006/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com