gpt4 book ai didi

php/simplexml - LIBXML 选项被忽略?

转载 作者:行者123 更新时间:2023-12-02 03:08:21 25 4
gpt4 key购买 nike

我正在尝试使用 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>&#x145;</foo></root>

正如您所看到的,这些标志中没有一个执行任何操作 - 实体仍然被转义(即使 XML 应该只根据 https://www.w3.org/TR/xml/#syntax 转义 "'&>< ),XML 声明仍然存在,并且空的标签保持为空。有没有办法使用 SimpleXML 达到预期的结果?或者至少只转义 5 个特殊字符? addChild()此处不是一个选项,我正在分配现有节点。

最佳答案

这些常量的命名可能有点神秘。那么实际上支持什么?

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 借自相关问答: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 ,这是我知道的 SimpleXMLElement (和 DOMDocument)的唯一方法。这里的输出:

<?xml version="1.0" encoding="UTF-8"?>
<root><empty_tag/><foo>Ņ</foo></root>

您再也看不到 Ņ 实体,而只是 Unicode(UTF-8 编码)形式的 ŅXML declaration 现在还显示编码。

根据您的问题,我认为这就是您正在寻找的LIBXML_NOENT

LIBXML_NOXMLDECL

列表中的第二个。我从来没有让它工作过,它有错误和/或有一些特定的版本要求,但老实说我什至不知道是否/在哪里有意应用它。

您可以从输出中删除包含 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>

或者为了执行此“纯”SimpleXML,在每个空元素中添加一个空文本节点:

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

我希望这能为您提供所需的选择。

关于php/simplexml - LIBXML 选项被忽略?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58375610/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com