Accessing processing instructions with PHP's SimpleXML

家住魔仙堡 提交于 2021-01-29 17:51:58

问题


Pretty straightforward -- Is there any way to access the data of a processing instruction node using SimpleXML? I understand that SimpleXML is, well, simple; as a result it has a number of limitations, predominantly working with mixed content nodes.

An example:

Test.xml

<test>
    <node>
        <?php /* processing instructions */ ?>
    </node>
</test>

Parse.php

$test = simplexml_load_file('Test.xml');
var_dump($test->node->php); // dumps as a SimpleXMLElement, so it's sorta found,
                            // however string casting and explicitly calling
                            // __toString() yields an empty string

So is this simply a technical limitation imposed by the simplicity of SimpleXML, or is there a way? I'll transition to SAX or DOM if necessary, but the SimpleXML would be nice.


回答1:


The problem is that < ? php ? > is considered a tag... so it gets parsed into a single big tag element. You'd need to do:

$xml = file_get_contents('myxmlfile.xml');
$xml = str_replace('<?php', '<![CDATA[ <?php', $xml);
$xml = str_replace('?>', '?> ]]>', $xml);
$xml = simplexml_load_string($xml, "SimpleXMLElement", LIBXML_NOCDATA);

I'm not entirely sure this would work, but i think it will. Test it out...




回答2:


The SimpleXML node you access here:

$test->node->php

somehow is that processing-instruction. But it also somehow is not. As long as there are not further elements with the same name, you can change the contents of the processing instruction:

$test->node->php = 'Yes Sir, I can boogie. ';

$test->asXML('php://output');

This creates the following output:

<?xml version="1.0"?>
<test>
    <node>
        <?php Yes Sir, I can boogie. ?>
    </node>
</test>

The original value of that processing instruction has been overwritten.

However only writing to that property does not mean you can access it also for reading. As you've found out yourself, it's a one-way road.

In SimpleXML in general you should consider processing instructions not to exist. They are still in the document but SimpleXML does not really give access to those.

DOMDocument allows you to do that instead and it works together with simplexml:

$doc   = dom_import_simplexml($test)->ownerDocument;
$xpath = new DOMXPath($doc);

# prints "/* processing instructions */ ", the value of the first PI:

echo $xpath->evaluate('string(//processing-instruction("php")[1])');


来源:https://stackoverflow.com/questions/8669707/accessing-processing-instructions-with-phps-simplexml

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!