如何防止 php simplexml 中的自关闭标签

问题描述 投票:0回答:6

我想使用 php simplexml 生成 xml。

$xml = new SimpleXMLElement('<xml/>');

$output = $xml->addChild('child1');
$output->addChild('child2', "value");
$output->addChild('noValue', '');

Header('Content-type: text/xml');
print($xml->asXML());

输出为

<xml>
   <child1>
      <child2>value</child2>
      <noValue/>
   </child1>
</xml>

我想要的是,如果标签没有值,它应该像这样显示

<noValue></noValue>

我尝试过使用

LIBXML_NOEMPTYTAG
中的 关闭 SimpleXML for PHP 中的自闭合标签?

我已经尝试过

$xml = new SimpleXMLElement('<xml/>', LIBXML_NOEMPTYTAG);
但不起作用。所以我不知道该把它放在哪里
LIBXML_NOEMPTYTAG

php xml simplexml
6个回答
22
投票
根据

spec

LIBXML_NOEMPTYTAG 不适用于 simplexml:

此选项目前仅在 DOMDocument::save 和 DOMDocument::saveXML 函数中可用。

要实现您的目标,您需要将 simplexml 对象转换为 DOMDocument 对象:

$xml = new SimpleXMLElement('<xml/>');
$child1 = $xml->addChild('child1');
$child1->addChild('child2', "value");
$child1->addChild('noValue', '');
$dom_sxe = dom_import_simplexml($xml);  // Returns a DomElement object

$dom_output = new DOMDocument('1.0');
$dom_output->formatOutput = true;
$dom_sxe = $dom_output->importNode($dom_sxe, true);
$dom_sxe = $dom_output->appendChild($dom_sxe);

echo $dom_output->saveXML($dom_output, LIBXML_NOEMPTYTAG);

返回:

<?xml version="1.0" encoding="UTF-8"?>
<xml>
  <child1>
    <child2>value</child2>
    <noValue></noValue>
  </child1>
</xml>

值得指出的事情... NOEMPTYTAG 选项可用于 DOMDocument 而不是 simplexml 的可能原因是空元素不被视为有效的 XML,而 DOM 规范允许它们。您正在用头撞墙来获取无效的 XML,这可能表明有效的自关闭空元素也可以正常工作。


8
投票

尽管已经给出了相当长的答案 - 这并不是特别错误,并且确实揭示了一些 libxml 库内部结构及其 PHP 绑定 - 你最有可能正在寻找:

$output->noValue = '';

添加开放标签、空节点值和结束标签(已美化,演示在这里:http://3v4l.org/S2PKc):

<?xml version="1.0"?>
<xml>
  <child1>
    <child2>value</child2>
    <noValue></noValue>
  </child1>
</xml>

只是注意到现有答案似乎忽略了这一点。


1
投票

既然简单的 XML 被证明很麻烦,也许 XMLWriter 可以做你想做的事。

这是一个小提琴

<?php

$oXMLWriter = new XMLWriter;
$oXMLWriter->openMemory();
$oXMLWriter->startDocument('1.0', 'UTF-8');

$oXMLWriter->startElement('xml');
$oXMLWriter->writeElement('child1', 'Hello world!!');
$oXMLWriter->writeElement('noValue', '');
$oXMLWriter->endElement();

$oXMLWriter->endDocument();
echo htmlentities($oXMLWriter->outputMemory(TRUE));

?>

输出:

<?xml version="1.0" encoding="UTF-8"?>
  <xml>
    <child1>Hello world!!</child1>
    <noValue></noValue>
  </xml>

0
投票

延伸自我的评论(有些已被删除):

行为取决于您的环境。相同的代码:

$xml = new SimpleXMLElement('<xml/>', LIBXML_NOEMPTYTAG);

$output = $xml->addChild('child1');
$output->addChild('child2', "value");
$output->addChild('noValue', '');

echo $xml->asXML();

3v4l.orgIdeone.com 中,它生成自关闭标签;
eval.incodepad.org 和我的本地主机(PHP 5.3/5.4、libXML 2.7、Windows)中,它会生成空标签。

由于根据 PHP 文档

LIBXML_NOEMPTYTAG
只能(保证)在
DOM
中工作,您可能需要尝试
DOM
以确保:

$dom=new DOMDocument("1.0","UTF-8");
$dom->formatOutput=true;
$root=$dom->createElement("xml");
$dom->appendChild($root);
$child1=$dom->createElement("child1");
$root->appendChild($child1);
$node=$dom->createElement("child2");
$node->appendChild($dom->createTextNode("value"));
$child1->appendChild($node);
$node=$dom->createElement("noValue");
$child1->appendChild($node);
echo $dom->saveXML($dom,LIBXML_NOEMPTYTAG);

3v4l.org 演示.

编辑

以上所有在线演示站点均默认使用

Content-Type: text/plain
。如果你想直接将XML作为独立资源输出到浏览器,你可以在输出前指定标头:

header("Content-Type: text/xml");
echo $dom->saveXML($dom,LIBXML_NOEMPTYTAG);

0
投票

我必须获取子节点并为 nodeValue 属性分配一个空字符串,然后 xml 关闭标记就会出现。

$output->childNodes[1]->nodeValue = '';

问候。


0
投票

不幸的是,这里提出的所有解决方案都没有帮助我。我必须使用

preg_replace
函数处理结果。如果属性名称中包含字母和数字以外的任何内容,请更正模板。

echo preg_replace("/\<([\w\d]+)\/\>/ui", "<$1></$1>", $xml->asXML());
© www.soinside.com 2019 - 2024. All rights reserved.