php - PHP simpleXMLelment xpath 返回意外结果
问题描述
我在问题底部的示例 XML 上执行了以下代码,我得到了意想不到的结果。
$xml = simplexml_load_string($xml_string);
$addresses = $xml->response->addressinformation;
var_dump($addresses->xpath('//record'));
我希望这只会返回record
当前节点的两个子addresses
节点。但是,它实际上返回record
了原始$xml
元素的所有 5 个节点。我读过的所有内容都表明该//
符号是相对于当前节点的。我意识到还有其他方法可以获取我在问题中引用的两条记录。$addresses->xpath('records/record');
只是一个例子。但是,奇怪的行为是我遇到的一个更大问题的一部分,我只需要了解它为什么会这样。我读过的所有东西都会让我相信。谁能帮我理解?
示例 XML
$xml_string = '
<?xml version="1.0" encoding="utf-8"?>
<root>
<response>
<addressinformation>
<records>
<record id="1">
<fullname>JOHN E DOE</fullname>
<firstname>JOHN</firstname>
<middlename>E</middlename>
<lastname>DOE</lastname>
<fulldob>01/01/1970</fulldob>
</record>
<record id="2">
<fullname>JOHN E DOE</fullname>
<firstname>JOHN</firstname>
</record>
</records>
</addressinformation>
<otherinformation>
<records>
<record id="3">
<fullname>JOHN DOE</fullname>
<firstname>JOHN</firstname>
<lastname>DOE</lastname>
<fulldob>01/01/1970</fulldob>
</record>
<record id="4">
<fullname>JOHN EDWARD DOE</fullname>
<firstname>JOHN</firstname>
<middlename>EDWARD</middlename>
<lastname>DOE</lastname>
<fulldob>19700000</fulldob>
</record>
<record id="5">
<fullname>JOHN EDWARD DOE</fullname>
<firstname>JOHN</firstname>
<middlename>EDWARD</middlename>
<lastname>DOE</lastname>
<fulldob>19830000</fulldob>
</record>
</records>
</otherinformation>
</response>
</root>
';
解决方案
根据https://www.w3.org/TR/1999/REC-xpath-19991116/:
//para
选择文档根的所有 para 后代,因此选择同一文档中的所有 para 元素作为上下文节点
和
.//para
选择上下文节点的 para 元素后代
注意后一个点之前的点。这也适用于您的情况:
var_dump($addresses->xpath('.//record'));
仅正确显示您期望的两个节点。
问题是 - 显然 - 即使所有对象都只是 type SimpleXMLElement
,您通过调用创建的第一个对象simplexml_load_string()
由于某种原因被认为是文档根。当您将文档“破坏”为节点和子节点时,这一切对我来说都是有意义的。
但是,我同意这至少是 PHP 文档中未记录的某些行为,因此我建议您建议在那里进行编辑。
推荐阅读
- python - 为什么密集层的形状是(无,50176)?
- zustand - Zusand 错误:无效的挂钩调用。Hooks 只能在函数组件的主体内部调用
- java - 如何以编程方式更改 RadioButton 背景的可绘制颜色?
- django-rest-framework - Django Rest Framework 可浏览 API [未找到渲染器]
- html - 选择 div 内的元素
- c++ - 是否可以在单独的 ui 文件中指定 Stacked Widget 的每一页
- bash - 在ansible中以root身份登录后执行任务
- javascript - imask 和 Vue:数字掩码中的意外小数
- android - NavigationComponent: NavHostFragment inside a fragment
- keycloak - Keycloak 2 条件验证器