37

is there an option with DomDocument to remove the first line:

<?xml version="1.0" encoding="UTF-8"?>

The class instantiation automatically adds it to the output, but is it possible to get rid of it?

4
  • 31
    $dom->saveXML($dom->documentElement); Commented Aug 21, 2012 at 17:53
  • 1
    You don't need navigate through childNodes, just save document root element: solution of @Tiberi-Ionut Stan. ;) Commented Nov 9, 2012 at 10:43
  • LIBXML_NOXMLDECL ; see also remove xml version tag when a xml is created in php Commented Feb 18, 2013 at 18:21
  • 2
    $dom->saveXML($dom->documentElement) excludes the XML declaration indeed, but does not keep the DTD, which is often very important (read IE). On the other side, the LIBXML_NOXMLDECL flag seems not to be supported yet, so the answer chosen seems to me a good compromise. Commented Sep 7, 2014 at 19:16

5 Answers 5

37

I think using DOMDocument is a universal solution for valid XML files:

If you have XML already loaded in a variable:

$t_xml = new DOMDocument();
$t_xml->loadXML($xml_as_string);
$xml_out = $t_xml->saveXML($t_xml->documentElement);

For XML file from disk:

$t_xml = new DOMDocument();
$t_xml->load($file_path_to_xml);
$xml_out = $t_xml->saveXML($t_xml->documentElement);

This comment helped: http://www.php.net/manual/en/domdocument.savexml.php#88525

Sign up to request clarification or add additional context in comments.

1 Comment

This is a much better solution than the accepted one. Take my +1
15

If you want to output HTML, use the saveHTML() function. It automatically avoids a whole lot of XML idiom and handles closed/unclosed HTML idiom properly.

If you want to output XML you can use the fact that DOMDocument is a DOMNode (namely: '/' in XPath expression), thus you can use DOMNode API calls on it to iterate over child nodes and call saveXML() on each child node. This does not output the XML declaration, and it outputs all other XML content properly.

Example:

$xml = get_my_document_object();
foreach ($xml->childNodes as $node) {
   echo $xml->saveXML($node);
}

4 Comments

Yes, it will. (Btw, the OP would not have accepted the answer if it brutally mangled his output like that...) Have you actually tried it?
@user268396 yeah, you were right. That foreach is just a trick, and a well formed XML would only server one node to that foreach.
!This solution is not correct in my opinion. The correct one is @hrvoj3e (!)
@PeterKrauss try it with the following string and observe the differences in output: "<!DOCTYPE might-be-important><?xml-stylesheet type='text/xsl' href='now-you-see-me-now-you-dont.xsl'?><root/>". Which one is correct, if all you want to do is remove the XML prolog?
3

I had the same problem, but I am using symfony/serializer for XML creation. If you also want to achieve this with Symfony serializer you can do in this way:

$encoder = new \Symfony\Component\Serializer\Encoder\XmlEncoder();

$encoder->encode($nodes[$rootNodeName], 'xml', [
    XmlEncoder::ROOT_NODE_NAME => $rootNodeName,
    XmlEncoder::ENCODING       => $encoding,
    XmlEncoder::ENCODER_IGNORED_NODE_TYPES => [
          XML_PI_NODE, //this flag is the solution
    ],
]);

Comments

0

For me, none of the answers above worked:

$dom = new \DOMDocument();
$dom->loadXXX('<?xml encoding="utf-8" ?>' . $content);  // loadXML or loadHTML
$dom->saveXML($dom->documentElement);

The above didn't work for me if I had partial HTML, e.g.

<p>Lorem</p>
<p>Ipsum</p>

As it then removed the everything after <p>Lorem</p>.

The only solution that worked for me was:

foreach ($doc->childNodes as $xx) {
    if ($xx instanceof \DOMProcessingInstruction) {
        $xx->parentNode->removeChild($xx);
    }
}

Comments

-1

You can use output buffering to remove it. A bit of a hack but it works.

ob_start();

// dom stuff

$output = ob_get_contents();
ob_end_clean();

$clean = preg_replace("/(.+?\n)/","",$output);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.