Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/272.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

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
使用PHP SimpleXML Xpath解析带有名称空间的XML时出现问题_Php_Xpath_Namespaces_Simplexml - Fatal编程技术网

使用PHP SimpleXML Xpath解析带有名称空间的XML时出现问题

使用PHP SimpleXML Xpath解析带有名称空间的XML时出现问题,php,xpath,namespaces,simplexml,Php,Xpath,Namespaces,Simplexml,有几篇文章是关于PHP和SimpleXML以及名称空间的,但是没有一篇能够解决我面临的挑战。这里是一个小的XML体,代表我遇到麻烦的一个较大的XML体,尽管如此,挑战是相同的。我无法获取任何xpath查询来返回所需的数据。注意以下几点 $xml = <<<EOD <blah:book xmlns:chap="http://example.org/chapter-title" xmlns:blah="urn:blah"> <blah:wrap>

有几篇文章是关于PHP和SimpleXML以及名称空间的,但是没有一篇能够解决我面临的挑战。这里是一个小的XML体,代表我遇到麻烦的一个较大的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;
当“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;
我已尝试注册命名空间:

$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')

返回可以从中获取第一项的数组。这将是您可以使用该方法并传递名称空间的类型形式

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

例如:

$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();
        }
    }
}
$xml=title)){
$bookTitle=$res->title->\uuuuToString();
}
如果(isset($res->章节)){
foreach($res->章为$chapter){
$chapterTitle=$chapter->title->\uuuu toString();
$chapterPara=$chapter->para->;
}
}
}

这对我来说不太合适。我需要的是能够在多维数组中恢复所有内容,就像没有名称空间一样。虽然这可能会使我在前额疼痛后得到类似的结果,但这需要我事先知道元素名称,而这并不是我想要达到的目的。
$result = $sxe->xpath('/node()/chap:*/*');
$result = $sxe->xpath('/node()/*/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;

$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();
        }
    }
}