php/simplexml - LIBXML 选项被忽略了吗?
php/simplexml - LIBXML options ignored?
我正在尝试使用 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 来达到预期的效果?或者至少 make 只转义 5 个特殊字符? addChild()
不是这里的选项,我正在分配现有节点。
您需要添加 XML 文档使用 UTF-8 编码的事实,例如...
$xml = '<?xml version="1.0" encoding="utf-8" ?><root><empty_tag/><foo></foo></root>';
给你...
<?xml version="1.0" encoding="utf-8"?>
<root><empty_tag/><foo>Ņ</foo></root>
这些常量的命名可能有点含糊。那么实际支持什么?
LIBXML_NOENT
实体是作为实体引用添加到文档中还是已展开。需要加载文档指定:
<?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借用了相关问答:
这与您的文档中的非 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
,这是我知道的 SimpleXMLElement
(和 DOMDocument
)的唯一方法。这里输出:
<?xml version="1.0" encoding="UTF-8"?>
<root><empty_tag/><foo>Ņ</foo></root>
您看不到更多 Ņ
实体,而只是 Ņ
Unicode(UTF-8 编码)实体。 XML declaration 现在也显示编码。
根据你的问题,我认为这就是你要找的 "for" LIBXML_NOENT
.
LIBXML_NOXMLDECL
列表中的第二个。我从来没有让它工作,它有问题 and/or 有一些特定的版本要求,但老实说我什至不知道 if/where 有意应用它。
您可以从输出中删除包含 XML 声明的第一行(始终以“\n
”结尾)。
或者您可以再次与基础 DOMDocument
相关以输出文档元素,因此它不是完整的文档,因此没有 XML 声明:
$dom = dom_import_simplexml($simpleXml)->ownerDocument;
echo $dom->saveXML($dom->documentElement);
输出:
<root><empty_tag/><foo>Ņ</foo></root>
这基本上是建议的内容:remove xml version tag when a xml is created in php。
LIBXML_NOEMPTYTAG
列表中的第三个也是最后一个。我现在可以从 PHP 手册中引用,但这已经在其他地方完成 on site already 但无论如何,如何使用 SimpleXMLElement
执行此操作而不考虑常量不可用?
一种方法是再次通过 DOMDocument
提供选项:
$dom = dom_import_simplexml($simpleXml)->ownerDocument;
echo $dom->saveXML($dom->documentElement, LIBXML_NOEMPTYTAG);
输出:
<root><empty_tag></empty_tag><foo>Ņ</foo></root>
或者这样做 "pure" 简单 XML,每个空元素中的空文本节点:
$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();
在 foreach
中,获取每个 xpath 查询的所有空元素,然后将其文本内容设置为空字符串,如果没有,它将在其中插入一个文本节点(一个空的)一个呢。输出:
<?xml version="1.0" encoding="UTF-8"?>
<root><empty_tag></empty_tag><foo>Ņ</foo></root>
我希望这能为您提供所需的选项。
我正在尝试使用 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 来达到预期的效果?或者至少 make 只转义 5 个特殊字符? addChild()
不是这里的选项,我正在分配现有节点。
您需要添加 XML 文档使用 UTF-8 编码的事实,例如...
$xml = '<?xml version="1.0" encoding="utf-8" ?><root><empty_tag/><foo></foo></root>';
给你...
<?xml version="1.0" encoding="utf-8"?>
<root><empty_tag/><foo>Ņ</foo></root>
这些常量的命名可能有点含糊。那么实际支持什么?
LIBXML_NOENT
实体是作为实体引用添加到文档中还是已展开。需要加载文档指定:
<?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借用了相关问答:
这与您的文档中的非 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
,这是我知道的 SimpleXMLElement
(和 DOMDocument
)的唯一方法。这里输出:
<?xml version="1.0" encoding="UTF-8"?>
<root><empty_tag/><foo>Ņ</foo></root>
您看不到更多 Ņ
实体,而只是 Ņ
Unicode(UTF-8 编码)实体。 XML declaration 现在也显示编码。
根据你的问题,我认为这就是你要找的 "for" LIBXML_NOENT
.
LIBXML_NOXMLDECL
列表中的第二个。我从来没有让它工作,它有问题 and/or 有一些特定的版本要求,但老实说我什至不知道 if/where 有意应用它。
您可以从输出中删除包含 XML 声明的第一行(始终以“\n
”结尾)。
或者您可以再次与基础 DOMDocument
相关以输出文档元素,因此它不是完整的文档,因此没有 XML 声明:
$dom = dom_import_simplexml($simpleXml)->ownerDocument;
echo $dom->saveXML($dom->documentElement);
输出:
<root><empty_tag/><foo>Ņ</foo></root>
这基本上是建议的内容:remove xml version tag when a xml is created in php。
LIBXML_NOEMPTYTAG
列表中的第三个也是最后一个。我现在可以从 PHP 手册中引用,但这已经在其他地方完成 on site already 但无论如何,如何使用 SimpleXMLElement
执行此操作而不考虑常量不可用?
一种方法是再次通过 DOMDocument
提供选项:
$dom = dom_import_simplexml($simpleXml)->ownerDocument;
echo $dom->saveXML($dom->documentElement, LIBXML_NOEMPTYTAG);
输出:
<root><empty_tag></empty_tag><foo>Ņ</foo></root>
或者这样做 "pure" 简单 XML,每个空元素中的空文本节点:
$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();
在 foreach
中,获取每个 xpath 查询的所有空元素,然后将其文本内容设置为空字符串,如果没有,它将在其中插入一个文本节点(一个空的)一个呢。输出:
<?xml version="1.0" encoding="UTF-8"?>
<root><empty_tag></empty_tag><foo>Ņ</foo></root>
我希望这能为您提供所需的选项。