PHP simpleXMLelment xpath returns 意外的结果
PHP simpleXMLelment xpath returns unexpected results
我在问题底部的示例 XML 上执行了以下代码,但得到了意想不到的结果。
$xml = simplexml_load_string($xml_string);
$addresses = $xml->response->addressinformation;
var_dump($addresses->xpath('//record'));
我希望这只 return 两个 record
节点是当前 addresses
节点的子节点。但是,它实际上是 return 原始 $xml
元素的所有 5 个 record
节点。我读过的所有内容都说 //
符号是相对于当前节点的。我意识到还有其他方法可以获取我在问题中引用的两条记录。 $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
selects all the para descendants of the document root and thus selects all para elements in the same document as the context node
和
.//para
selects the para element descendants of the context node
注意后一个之前的点。这也适用于您的情况:
var_dump($addresses->xpath('.//record'));
正确地只显示了您期望的两个节点。
事情是 - 显然 - 即使所有对象都只是类型 SimpleXMLElement
,您通过调用 simplexml_load_string()
创建的第一个对象出于某种原因被认为是文档根。当您将文档“分解”为节点和子节点时,这一切对我来说都很有意义。
但是 我同意这至少是 PHP 文档中未记录的某些行为,因此我建议您在那里提出编辑建议。
我在问题底部的示例 XML 上执行了以下代码,但得到了意想不到的结果。
$xml = simplexml_load_string($xml_string);
$addresses = $xml->response->addressinformation;
var_dump($addresses->xpath('//record'));
我希望这只 return 两个 record
节点是当前 addresses
节点的子节点。但是,它实际上是 return 原始 $xml
元素的所有 5 个 record
节点。我读过的所有内容都说 //
符号是相对于当前节点的。我意识到还有其他方法可以获取我在问题中引用的两条记录。 $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
selects all the para descendants of the document root and thus selects all para elements in the same document as the context node
和
.//para
selects the para element descendants of the context node
注意后一个之前的点。这也适用于您的情况:
var_dump($addresses->xpath('.//record'));
正确地只显示了您期望的两个节点。
事情是 - 显然 - 即使所有对象都只是类型 SimpleXMLElement
,您通过调用 simplexml_load_string()
创建的第一个对象出于某种原因被认为是文档根。当您将文档“分解”为节点和子节点时,这一切对我来说都很有意义。
但是 我同意这至少是 PHP 文档中未记录的某些行为,因此我建议您在那里提出编辑建议。