带有 simplexml 的 xpath 无法访问嵌套元素
xpath with simplexml not able to access nested element
我有一个 xml 像这样:
<?xml version="1.0" encoding="UTF-8"?>
<foo SeqNum="1">
<bar>1234</bar>
</foo>
<foo SeqNum="20">
<bar>6789</bar>
</foo>
我正在尝试通过此查询获取值 6789
:
$xml = "<?xml version="1.0" encoding="UTF-8"?>
<foo SeqNum="1">
<bar>1234</bar>
</foo>
<foo SeqNum="20">
<bar>6789</bar>
</foo>";
$simple = new SimpleXMLElement($xml);
$result = $simple->xpath('//*[@SeqNum="20"]/bar/'); // result gives me nothing
所以我试着像这样得到 parent
$result = $simple->xpath('//*[@SeqNum="20"]')[0]->asXML();
这给了我:
<foo SeqNum="20">
<bar>6789</bar>
</foo>
所以我快到了,但我真的对我不理解的东西感到困惑。谢谢!
题中有几个错误。 XML 需要一个根元素,而尾部的 /
会中断表达式。文字引号需要改为单引号(或者所有内部双引号需要转义。)
固定示例:
$xml = '<?xml version="1.0" encoding="UTF-8"?>
<foo>
<foo SeqNum="1">
<bar>1234</bar>
</foo>
<foo SeqNum="20">
<bar>6789</bar>
</foo>
</foo>';
$simple = new SimpleXMLElement($xml);
$result = $simple->xpath('//*[@SeqNum="20"]/bar');
var_dump((string)$result[0]);
输出:
string(4) "6789"
有命名空间
如果您的 XML 使用命名空间,您必须为此命名空间 URI 定义 alias/prefix 并在 Xpath 表达式中使用它。
$xml = <<<'XML'
<?xml version="1.0" encoding="UTF-8" ?>
<p:foo xmlns:p="http://www.example.com">
<p:foo SeqNum="1">
<p:bar>1234</p:bar>
</p:foo>
<p:foo SeqNum="20">
<p:bar>6789</p:bar>
</p:foo>
</p:foo>
XML;
$simple = new SimpleXMLElement($xml);
$simple->registerXpathNamespace('e', 'http://www.example.com');
$result = $simple->xpath('//*[@SeqNum="20"]/e:bar');
var_dump((string)$result[0]);
该示例对表达式使用了不同的别名,以表明文档和表达式是分开的 - 只有名称空间 URI 必须匹配。
命名空间必须是唯一的,因此它们是用 URI(URL 的超集)定义的。因为那样会变得混乱,所以在节点名称中使用了别名。下面3个元素都可以读作{http://www.example.com}bar
.
<p:bar xmlns:p="http://www.example.com"/>
<e:bar xmlns:e="http://www.example.com"/>
<bar xmlns="http://www.example.com"/>
我有一个 xml 像这样:
<?xml version="1.0" encoding="UTF-8"?>
<foo SeqNum="1">
<bar>1234</bar>
</foo>
<foo SeqNum="20">
<bar>6789</bar>
</foo>
我正在尝试通过此查询获取值 6789
:
$xml = "<?xml version="1.0" encoding="UTF-8"?>
<foo SeqNum="1">
<bar>1234</bar>
</foo>
<foo SeqNum="20">
<bar>6789</bar>
</foo>";
$simple = new SimpleXMLElement($xml);
$result = $simple->xpath('//*[@SeqNum="20"]/bar/'); // result gives me nothing
所以我试着像这样得到 parent
$result = $simple->xpath('//*[@SeqNum="20"]')[0]->asXML();
这给了我:
<foo SeqNum="20">
<bar>6789</bar>
</foo>
所以我快到了,但我真的对我不理解的东西感到困惑。谢谢!
题中有几个错误。 XML 需要一个根元素,而尾部的 /
会中断表达式。文字引号需要改为单引号(或者所有内部双引号需要转义。)
固定示例:
$xml = '<?xml version="1.0" encoding="UTF-8"?>
<foo>
<foo SeqNum="1">
<bar>1234</bar>
</foo>
<foo SeqNum="20">
<bar>6789</bar>
</foo>
</foo>';
$simple = new SimpleXMLElement($xml);
$result = $simple->xpath('//*[@SeqNum="20"]/bar');
var_dump((string)$result[0]);
输出:
string(4) "6789"
有命名空间
如果您的 XML 使用命名空间,您必须为此命名空间 URI 定义 alias/prefix 并在 Xpath 表达式中使用它。
$xml = <<<'XML'
<?xml version="1.0" encoding="UTF-8" ?>
<p:foo xmlns:p="http://www.example.com">
<p:foo SeqNum="1">
<p:bar>1234</p:bar>
</p:foo>
<p:foo SeqNum="20">
<p:bar>6789</p:bar>
</p:foo>
</p:foo>
XML;
$simple = new SimpleXMLElement($xml);
$simple->registerXpathNamespace('e', 'http://www.example.com');
$result = $simple->xpath('//*[@SeqNum="20"]/e:bar');
var_dump((string)$result[0]);
该示例对表达式使用了不同的别名,以表明文档和表达式是分开的 - 只有名称空间 URI 必须匹配。
命名空间必须是唯一的,因此它们是用 URI(URL 的超集)定义的。因为那样会变得混乱,所以在节点名称中使用了别名。下面3个元素都可以读作{http://www.example.com}bar
.
<p:bar xmlns:p="http://www.example.com"/>
<e:bar xmlns:e="http://www.example.com"/>
<bar xmlns="http://www.example.com"/>