使用PHP的SimpleXML访问处理指令

时间:2011-12-29 15:27:38

标签: php xml simplexml processing-instruction

非常简单 - 有没有办法使用SimpleXML访问处理指令节点的数据?我知道SimpleXML很简单;因此,它有许多限制,主要是使用混合内容节点。

一个例子:

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

这仅仅是SimpleXML简单性所带来的技术限制,还是有办法?如果需要,我将转换到SAX或DOM,但SimpleXML会很好。

2 个答案:

答案 0 :(得分:1)

问题在于&lt; ? PHP? &GT;被认为是一个标签...所以它被解析成一个大的标签元素。你需要这样做:

$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);

我不完全确定这会起作用,但我认为会这样。测试一下......

答案 1 :(得分:1)

您在此处访问的SimpleXML节点:

$test->node->php

不知何故是处理指令。但它也不知何故。只要没有其他具有相同名称的元素,您就可以更改处理指令的内容:

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

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

这会创建以下输出:

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

该处理指令的原始值已被覆盖。

但是,只写入该属性并不意味着您也可以访问该属性进行阅读。正如你自己发现的那样,这是一条单行道。

在SimpleXML中,您应该考虑不存在的处理指令。它们仍在文档中,但SimpleXML并不能真正访问这些文档。

DOMDocument允许您这样做,它与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])');