gpt4 book ai didi

php - 使用 PHP SimpleXML Xpath 解析带有命名空间的 XML 时遇到问题

转载 作者:行者123 更新时间:2023-12-04 16:52:12 25 4
gpt4 key购买 nike

有几篇与带有命名空间的 PHP 和 SimpleXML 相关的文章,但没有一篇文章能够解决我面临的挑战。这里有一小部分 XML 代表了一个较大的主体,但我遇到了问题,但挑战是相同的。我无法获得任何 xpath 查询来返回我想要的数据。请注意以下事项

$xml = <<<EOD
<blah:book xmlns:chap="http://example.org/chapter-title" xmlns:blah="urn:blah">
<blah:wrap>
<chap:wrap>
<title>My Book</title>
<chapter id="1">
<title>Chapter 1</title>
<para>Donec velit. Nullam eget tellus vitae</para>
</chapter>
<chapter id="2">
<title>Chapter 2</title>
<para>Lorem ipsum dolor sit amet</para>
</chapter>
</chap:wrap>
</blah:wrap>
</blah:book>
EOD;

"blah"和 "chap"的命名空间,因为它们在第一个主体中的位置似乎不构成问题。如果我使用 xpath 查询运行以下 php 代码,则会得到以下结果:
$sxe = new SimpleXMLElement($xml);
$result = $sxe->xpath('/node()/*/*');
var_dump($result);

// gives me
array(1) {
[0]=>
object(SimpleXMLElement)#2 (2) {
["title"]=>
string(7) "My Book"
["chapter"]=>
array(2) {
[0]=>
object(SimpleXMLElement)#4 (3) {
["@attributes"]=>
array(1) {
["id"]=>
string(1) "1"
}
["title"]=>
string(9) "Chapter 1"
["para"]=>
string(37) "Donec velit. Nullam eget tellus vitae"
}
[1]=>
object(SimpleXMLElement)#5 (3) {
["@attributes"]=>
array(1) {
["id"]=>
string(1) "2"
}
["title"]=>
string(9) "Chapter 2"
["para"]=>
string(26) "Lorem ipsum dolor sit amet"
}
}
}
}

当“chap”更普遍时会出现问题,例如:
$xml = <<<EOD
<blah:book xmlns:chap="http://example.org/chapter-title" xmlns:blah="urn:blah">
<blah:wrap>
<chap:wrap>
<chap:title>My Book</chap:title>
<chap:chapter id="1">
<chap:title>Chapter 1</chap:title>
<chap:para>Donec velit. Nullam eget tellus vitae</chap:para>
</chap:chapter>
<chap:chapter id="2">
<chap:title>Chapter 2</chap:title>
<chap:para>Lorem ipsum dolor sit amet</chap:para>
</chap:chapter>
</chap:wrap>
</blah:wrap>
</blah:book>
EOD;

之后,上面相同的 php 代码会产生以下结构:
array(1) {
[0]=>
object(SimpleXMLElement)#2 (0) {
}
}

我试过注册命名空间:
$sxe = new SimpleXMLElement($xml);
$sxe->registerXPathNamespace('chap', 'http://example.org/chapter-title');
$result = $sxe->xpath('/node()/*/*');
var_dump($result);

但结果还是一样:
array(1) {
[0]=>
object(SimpleXMLElement)#2 (0) {
}
}

我尝试了许多不同的 xpath 查询,其中没有一个会返回数组结构中的整个 xml 主体,如上图所示,从第一个 xml 主体开始。这是一对夫妇,但我出于绝望尝试了更疯狂的事情,但都没有奏效。
$result = $sxe->xpath('/node()/chap:*/*');
$result = $sxe->xpath('/node()/*/chap:*');

一些帖子建议删除所有命名空间,然后不必担心它,但是,应该有一种方法来解析它并检索整个主体,就像在第一个示例中一样。不幸的是,我空手而归。我也承认,我不明白为什么第一个主体中出现的“chap”命名空间不会导致初始 xpath 查询出现问题。我希望有人能指出我正确的方向。

最佳答案

也许一个可能的解决方案是使用它作为 xpath 表达式:

$result = $sxe->xpath('//blah:book/blah:wrap');



xpath返回一个数组,您可以从中获取第一项。这将是 SimpleXMLElement 类型您可以使用 children 的表格方法并传递命名空间。

您可以在 foreach 和 $res 中循环子项变量的类型为 SimpleXMLElement。然后您可以检查是否设置了属性并获取您的数据。

例如:
$xml = <<<EOD
<blah:book xmlns:chap="http://example.org/chapter-title" xmlns:blah="urn:blah">
<blah:wrap>
<chap:wrap>
<chap:title>My Book</chap:title>
<chap:chapter id="1">
<chap:title>Chapter 1</chap:title>
<chap:para>Donec velit. Nullam eget tellus vitae</chap:para>
</chap:chapter>
<chap:chapter id="2">
<chap:title>Chapter 2</chap:title>
<chap:para>Lorem ipsum dolor sit amet</chap:para>
</chap:chapter>
</chap:wrap>
</blah:wrap>
</blah:book>
EOD;

$sxe = new SimpleXMLElement($xml);

$result = $sxe->xpath('//blah:book/blah:wrap');
foreach ($result[0]->children('http://example.org/chapter-title') as $res) {
if (isset($res->title)) {
$bookTitle = $res->title->__toString();
}
if (isset($res->chapter)) {
foreach ($res->chapter as $chapter) {
$chapterTitle = $chapter->title->__toString();
$chapterPara = $chapter->para->__toString();
}
}
}

Demo

关于php - 使用 PHP SimpleXML Xpath 解析带有命名空间的 XML 时遇到问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35200449/

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