有一些与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查询出现问题。我希望有人能指出我正确的方向。
答案 0 :(得分:0)
也许一种可能的解决方案是将其用作xpath表达式:
$ result = $ sxe-&gt; xpath(&#39; // blah:book / blah:wrap&#39;);
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();
}
}
}