XML:
<order>
XXX
<orderValue>YYY</orderValue>
</order>
问题:
我不知道如何获得纯XXX(使用PHP的SimpleXMLElement),因为它无法通过直接标记访问$order->orderValue将交付YYY当然,$order会交付订单标签内的所有内容。根据codeeautify.org.validator和xmlwf shell验证器,XML是有效的。
您拥有的XML:
<order>
XXX
<orderValue>YYY</orderValue>
</order>
从技术上讲,与PHP中的Simplexml不兼容。尽管Clément Malet概述了这个微小的片段在他回答的孤立示例中确实有效,但您在这里指的是更普遍的问题,即Simplexml与数据访问不兼容,以实现文档节点的差异化(和可能的)排列。
不要误解我的意思,XML是有效的,Simplexml会加载它(它也不会破坏文档)。但是SimpleXMLElement的接口无法将这里的混合子节点寻址到您可能需要的详细级别:
- 文本节点CCD_ 1
- 元素节点CCD_ 2
Simplexml在技术上允许父元素只有一种类型的子节点,从而简化了对XML文档中数据的访问。所以只有元素或文本。
对于更具差异性的东西,有一个名为Dom的姐妹库,它可以互换工作。通过扩展SimpleXMLElement,您甚至可以在这里为现有代码创建一些扩展,而无需对其进行太多更改
让我们向SimpleXMLElement添加一个新方法,该方法返回您感兴趣的任何元素的所有子节点(文本节点和元素节点),并将该方法命名为childNodes:
/**
* Extend SimpleXMLElement to access child-nodes more differentiated.
*
* Demonstration to work together with DOM sister library
*/
class MyXml extends SimpleXMLElement
{
public function childNodes() {
$nodes = [];
foreach(dom_import_simplexml($this)->childNodes as $node) {
if ($node instanceof DOMText) {
$nodes[] = $node->nodeValue;
} elseif ($node instanceof DOMElement) {
$nodes[] = simplexml_import_dom($node);
} // ... other node-types ignored in this example
}
return $nodes;
}
}
根据创建SimpleXMLElement的方式,您可以传递一些参数,告诉要使用哪个SimpleXMLElement类。下面是我的字符串示例:
$buffer = <<<XML
<doc>
<order>
XXX <!-- XXX is never reachable as-is with pure SimpleXML -->
<orderValue>YYY</orderValue>
ZZZ <!-- same for ZZZ -->
</order>
</doc>
XML;
$xml = simplexml_load_string($buffer, 'MyXml');
我使用simplexml_load_string
函数创建了SimpleXMLElement。它有第二个参数,我可以在其中传递要使用的类名。这允许您使用添加的方法:
var_dump($xml->order->childNodes()[0]); // first child-node string(11) "'n XXX "
正如您所看到的,您可能无法使用"纯"Simplexml来实现这一点,但您可以扩展接口,并从DOM姐妹库提供的更详细的访问中获益。
您不需要瞄准任何东西,您已经在具有想要获得的值的节点上了
$xml = simplexml_load_string('
<order>
XXX
<orderValue>YYY</orderValue>
</order>
');
echo $xml;
输出XXX
在某些情况下,您可能必须使用echo (string) $xml;
。