我正在尝试将LIBXML *常量用于SimpleXMLElement
构造函数的第二个参数,但它们根本没有任何改变。
$xml = '<root><empty_tag/><foo></foo></root>';
$simpleXml = new SimpleXMLElement($xml, LIBXML_NOENT|LIBXML_NOXMLDECL|LIBXML_NOEMPTYTAG);
$simpleXml->foo = 'Ņ';
echo $simpleXml->asXML();
预期:
<root><empty_tag></empty_tag><foo>Ņ</foo></root>
实际:
<?xml version="1.0"?>
<root><empty_tag/><foo>Ņ</foo></root>
如您所见,这些标志中没有一个做任何事情-实体仍然被转义(即使XML仅应根据"'&><
来转义https://www.w3.org/TR/xml/#syntax),XML声明仍然存在,并且空标记保持为空。有没有一种使用SimpleXML达到预期结果的方法?还是至少只能逃避5个特殊字符? addChild()
在这里不是选项,我要分配现有的节点。
这些常量的命名可能有点神秘。那么实际上支持什么呢?
是将实体添加为对文档的实体引用,还是对其进行了扩展。需要通过加载文档来指定:
<?php
$xml = '<!DOCTYPE test [<!ENTITY c "TEST">]>
<test>&c;</test>';
echo (new SimpleXMLElement($xml))->asXML(), "\n";
echo (new SimpleXMLElement($xml, LIBXML_NOENT))->asXML(), "\n";
这显示第一个输出:
<?xml version="1.0"?>
<!DOCTYPE test [
<!ENTITY c "TEST">
]>
<test>&c;</test>
实体已保留。对于第二个回显,使用LIBXML_NOENT
:
<?xml version="1.0"?>
<!DOCTYPE test [
<!ENTITY c "TEST">
]>
<test>TEST</test>
XML是从相关的问答中借来的:What does LIBXML_NOENT do (and why isn't it called LIBXML_ENT)?
顺便说一下,这与文档中包含的非US-ASCII字符无关。如果需要带有文档的文档,请将编码设置为UTF-8,例如:
$xml = '<root><empty_tag/><foo></foo></root>';
$simpleXml = new SimpleXMLElement($xml);
dom_import_simplexml($simpleXml)->ownerDocument->encoding = 'UTF-8';
$simpleXml->foo = 'Ņ';
echo $simpleXml->asXML();
这里的诀窍是set the encoding in the underlying DOMDocument
,这是我知道DOMDocument
(和SimpleXMLElement
)的唯一方法。这里的输出:
DOMDocument
您再也看不到<?xml version="1.0" encoding="UTF-8"?>
<root><empty_tag/><foo>Ņ</foo></root>
实体,而只能看到Unicode(UTF-8编码)中的Ņ
。 Ņ
现在也显示编码。
根据您的问题,我想这就是您在寻找XML declaration的目的。
列表中的第二个。我从未使用过它,它的确有错误,并且/或者有一些特定的版本要求,但是老实说,我什至不知道是否有意/在哪里应用它。
您可以从输出中删除包含XML声明的第一行(始终以“ LIBXML_NOENT
”终止)。
或者您可以再次与基础\n
相关联以输出文档元素,因此它不是完整的文档,因此没有XML声明:
DOMDocument
输出:
$dom = dom_import_simplexml($simpleXml)->ownerDocument;
echo $dom->saveXML($dom->documentElement);
这基本上是在<root><empty_tag/><foo>Ņ</foo></root>
中建议的内容。
列表中的第三个也是最后一个。我现在可以引用PHP手册,但这已经在remove xml version tag when a xml is created in php其他地方完成了,但是无论如何,无论常量不可用,如何使用on site already来做到这一点?
一种方法是再次通过SimpleXMLElement
提供选项:
DOMDocument
输出:
$dom = dom_import_simplexml($simpleXml)->ownerDocument;
echo $dom->saveXML($dom->documentElement, LIBXML_NOEMPTYTAG);
或为了执行此“纯” SimpleXML,将空文本节点插入每个空元素:
<root><empty_tag></empty_tag><foo>Ņ</foo></root>
即在$xml = '<?xml version="1.0" encoding="UTF-8"?><root><empty_tag/><foo></foo></root>';
$simpleXml = new SimpleXMLElement($xml);
$simpleXml->foo = 'Ņ';
foreach ($simpleXml->xpath('//*[not(*) and string() = ""]') as $empty) {
$empty[0] = '';
}
echo $simpleXml->asXML();
中,以获取每个xpath查询的所有空元素,然后将其文本内容设置为一个空字符串,如果不存在(空),则将在其中插入一个文本节点然而。输出:
foreach
我希望这会为您提供所需的选项。
您将需要添加XML文档是使用UTF-8编码的事实,所以类似...
<?xml version="1.0" encoding="UTF-8"?>
<root><empty_tag></empty_tag><foo>Ņ</foo></root>
给你...
$xml = '<?xml version="1.0" encoding="utf-8" ?><root><empty_tag/><foo></foo></root>';