【问题标题】:How to retrieve a subsubchild using XPath?如何使用 XPath 检索子子项?
【发布时间】:2023-03-26 15:04:01
【问题描述】:

我正在测试一个 XML 结构:

<Articles>


...


   <Article ID="333">

     <author>Paul</author>

     <title>i hate xpath </title>

        <child1>bla</child1>

       <child2>blabla
          <subchild>
             <subsubchild DEEP = "Attribute"></subsubchild>     //this is my nightmare
          </subchild>
       </child2>

       <child3>testing</child3>

   </Article> 
...

</Articles>

什么 XPath 表达式将获取和更新 subsubchild 属性值?如果父 ID(在本例中为 333)已知,我最关心的是获取和更新任何节点的子值,无论其位置有多深或多浅。

目前我用过:

$query= "//*[@ID=333]//*node()[@DEEP and @DEEP = "Attribute"]";
$outcome = $xml->xpath($query);
    echo isset($outcome[0][0]) ? "found" : "unavailable";

还有其他几个相关的表达方式,它们都让我对 Invalid expression report 的努力感到沮丧。

function XMLChangeAttribValue($ParentID, $attirbName, $attribValue, $NewValue){
        
            $xml    //Never mind, i've create this sucessfully 

 
            $query = "//*[@ID=$ParentID]//*[@$attirbName = $attribValue]";
                    

            $outcome = $xml->xpath($query);
            echo isset($outcome[0][0]) ? "found" : "unavailable";
}

【问题讨论】:

  • 我不知道你的问题是什么。 “无效的表达式报告”是指 XPath 引擎报告错误吗?那么,请出示一下。你在使用 PHP 吗?然后,这样标记问题。 XPath 不是更新 XML 文档的正确工具,请将您的预期输出显示为 XML。
  • 不要发表个人言论 - 它们并不完全有助于为您的问题找到一个好的答案。不过,解决我的 cmets 会有所帮助。
  • 对不起,Mathias,如果我听起来不太好,我不是故意的,我只是对你说不能使用 xpath(或者更确切地说不是正确的工具)来更新 xml 感到惊讶。还有什么更好的?一个foreach循环?好吧,更新我的意思是我想将 DEEP(属性)的值更改为我选择的值。如果你有想法,请告诉我。再次接受我的道歉。
  • @OsagieOdigie,您的问题令人困惑,您在 cmets 中的回答也无济于事。 Mathias 非常“了解 wat 在地面上的情况”(对于对这种奇怪结构的任何合理解释),JLRishe 的回答是正确的。在你改进你的问题之前,我投票结束你在问什么不清楚:清晰的例子可以克服你可能遇到的任何英语流利度挑战,失去文字说话会显示对你的读者的尊重。谢谢。
  • 我同意@kjhughes,如果你可以将“wanna”改为“want to”,“wat”改为“what”,“u”改为“you”,“pls”改为“please” (等)非常感谢 - 在您的帖子和您的 cmets 中。说流利英语的人不要求完美,也不要求学术水平的正式,但同样我们不希望 Stack Overflow 成为聊天室(或者更糟糕的是,类似于 YouTube cmets)。 IMO,避免文字朗读是朝着正确方向迈出的一步。

标签: php xml xpath


【解决方案1】:

在这种情况下,选择 subsubchild 的 XPath 是:

$query = "//*[@ID=333]//*[@DEEP = 'Attribute']";

要选择属性本身,您可以使用:

$query = "//*[@ID=333]//*/@DEEP[. = 'Attribute']";

请注意,我在字符串中使用了单引号,因为您不能在双引号字符串中使用双引号,除非您对其进行转义。

还应注意,在 XPath 表达式中使用 *node() all in one clump 无效。

【讨论】:

  • 感谢@Rishe。但实际上,我在编译时不知道节点“subsubchild”(如果您不介意,也可以在测试时)。这就是我使用 xpath 的 node() 函数的原因。我还能如何在运行时获取节点名称?再次,我实际上想做一个选择所有的东西,如 "//*[@ID=333]//*(unknown node)... 来获取任何可用的匹配项。提前谢谢。
  • @OsagieOdigie 在元素名称未知的情况下,可以使用*。请看我上面的编辑。
  • 很抱歉打扰您。上面的函数(我的新编辑)显示了要模拟的内容。我试过你说的但仍然得到无效的表达。你看到了什么 d 错误?谢谢
  • @OsagieOdigie 你错过了$attribValue周围的引号:"//*[@ID=$ParentID]//*[@$attirbName = '$attribValue']"
  • @OsagieOdigie 我当然不知道。 $attirbName 来自哪里?它的价值在哪里?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-23
  • 2019-07-19
  • 2013-08-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多