How to prevent self closing tag in php simplexml

你离开我真会死。 提交于 2019-12-28 04:14:49

问题


I want to generate xml by using php simplexml.

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

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

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

The output is

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

What I want is if the tag has no value it should display like this

<noValue></noValue>

I've tried using LIBXML_NOEMPTYTAG from Turn OFF self-closing tags in SimpleXML for PHP?

I've tried $xml = new SimpleXMLElement('<xml/>', LIBXML_NOEMPTYTAG); and it doesn't work. So I don't know where to put the LIBXML_NOEMPTYTAG


回答1:


LIBXML_NOEMPTYTAG does not work with simplexml, per the spec:

This option is currently just available in the DOMDocument::save and DOMDocument::saveXML functions.

To achieve what you're after, you need to convert the simplexml object to a DOMDocument object:

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

which returns:

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

Something worth pointing out... the likely reason that the NOEMPTYTAG option is available for DOMDocument and not simplexml is that empty elements are not considered valid XML, while the DOM specification allows for them. You are banging your head against the wall to get invalid XML, which may suggest that the valid self-closing empty element would work just as well.




回答2:


Despite the quite lengthy answers already given - which are not particularly wrong and do shed some light into some libxml library internals and it's PHP binding - you're most likely looking for:

$output->noValue = '';

To add an open tag, empty node-value and end tag (beautified, demo is here: http://3v4l.org/S2PKc):

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

Just noting as it seems it has been overlooked with the existing answers.




回答3:


Since Simple XML is proving troublesome, perhaps XMLWriter could do what you want.

Here's a fiddle

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

?>

Output:

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



回答4:


Extending from my comments (some got deleted):

The behavior depends on your environment. This same code:

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

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

echo $xml->asXML();

In 3v4l.org and Ideone.com, it produces self-closing tag;
In eval.in, codepad.org and on my localhost (PHP 5.3/5.4, libXML 2.7, Windows), it produces empty tag.

Since according to PHP document, LIBXML_NOEMPTYTAG only (guarenteed to) work in DOM, you may want to try DOM for ensurance:

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

Edit:

All the above online demo site uses Content-Type: text/plain by default. If you want to directly output XML to browser as a standalone resource, you can specify the header before output:

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


来源:https://stackoverflow.com/questions/19629379/how-to-prevent-self-closing-tag-in-php-simplexml

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!