How to use PHP DOMDocument saveHTML($node) without added whitespace?










5















If I use saveHTML() without the optional DOMnode parameter it works as expected:



$html = '<html><body><div>123</div><div>456</div></body></html>';
$dom = new DOMDocument;
$dom->preserveWhiteSpace = true;
$dom->formatOutput = false;
$dom->loadHTML($html, LIBXML_HTML_NODEFDTD);
echo $dom->saveHTML();



<html><body><div>123</div><div>456</div></body></html>



But when I add a DOMNode parameter to output a subset of the document it seems to ignore the formatOutput property and adds a bunch of unwanted whitespace:



$body = $dom->getElementsByTagName('body')->item(0);
echo $dom->saveHTML($body);



<body>
<div>123</div>
<div>456</div>
</body>



What gives? Is this a bug? Is there a workaround?










share|improve this question


























    5















    If I use saveHTML() without the optional DOMnode parameter it works as expected:



    $html = '<html><body><div>123</div><div>456</div></body></html>';
    $dom = new DOMDocument;
    $dom->preserveWhiteSpace = true;
    $dom->formatOutput = false;
    $dom->loadHTML($html, LIBXML_HTML_NODEFDTD);
    echo $dom->saveHTML();



    <html><body><div>123</div><div>456</div></body></html>



    But when I add a DOMNode parameter to output a subset of the document it seems to ignore the formatOutput property and adds a bunch of unwanted whitespace:



    $body = $dom->getElementsByTagName('body')->item(0);
    echo $dom->saveHTML($body);



    <body>
    <div>123</div>
    <div>456</div>
    </body>



    What gives? Is this a bug? Is there a workaround?










    share|improve this question
























      5












      5








      5


      0






      If I use saveHTML() without the optional DOMnode parameter it works as expected:



      $html = '<html><body><div>123</div><div>456</div></body></html>';
      $dom = new DOMDocument;
      $dom->preserveWhiteSpace = true;
      $dom->formatOutput = false;
      $dom->loadHTML($html, LIBXML_HTML_NODEFDTD);
      echo $dom->saveHTML();



      <html><body><div>123</div><div>456</div></body></html>



      But when I add a DOMNode parameter to output a subset of the document it seems to ignore the formatOutput property and adds a bunch of unwanted whitespace:



      $body = $dom->getElementsByTagName('body')->item(0);
      echo $dom->saveHTML($body);



      <body>
      <div>123</div>
      <div>456</div>
      </body>



      What gives? Is this a bug? Is there a workaround?










      share|improve this question














      If I use saveHTML() without the optional DOMnode parameter it works as expected:



      $html = '<html><body><div>123</div><div>456</div></body></html>';
      $dom = new DOMDocument;
      $dom->preserveWhiteSpace = true;
      $dom->formatOutput = false;
      $dom->loadHTML($html, LIBXML_HTML_NODEFDTD);
      echo $dom->saveHTML();



      <html><body><div>123</div><div>456</div></body></html>



      But when I add a DOMNode parameter to output a subset of the document it seems to ignore the formatOutput property and adds a bunch of unwanted whitespace:



      $body = $dom->getElementsByTagName('body')->item(0);
      echo $dom->saveHTML($body);



      <body>
      <div>123</div>
      <div>456</div>
      </body>



      What gives? Is this a bug? Is there a workaround?







      php domdocument






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 13 '18 at 19:19









      billynoahbillynoah

      10.6k54362




      10.6k54362






















          3 Answers
          3






          active

          oldest

          votes


















          3














          If you know your document is going to be valid XML as well, you can use saveXML() instead...



          $html = '<html><body><div>123</div><div>456</div></body></html>';
          $dom = new DOMDocument;
          $dom->preserveWhiteSpace = true;
          $dom->formatOutput = false;
          $dom->loadHTML($html, LIBXML_HTML_NODEFDTD);
          $body = $dom->getElementsByTagName('body')->item(0);
          echo $dom->saveXML($body);


          which gives...



          <body><div>123</div><div>456</div></body>





          share|improve this answer

























          • Looking deeper into this, saveXML() respects the formatOutput property with or without the argument, while saveHTML() only works without argument. Seems like a bug to me. Thanks for the workaround!

            – billynoah
            Nov 13 '18 at 19:54


















          5















          Is this a bug?




          Yes, it's a bug and it's reported here




          Is there a workaround?




          Stick with Nigel's solution for now




          Did they fix it?




          Yes, as of 7.3.0 alpha3 this is a fixed bug



          Check it here






          share|improve this answer























          • wow, nice work finding that. thanks for the reference

            – billynoah
            Nov 14 '18 at 0:18


















          2














          Well, it's a pretty ugly workaround, but it gets the job done:



          $html = '<html><body><div>123</div><div>456</div></body></html>';
          $dom = new DOMDocument;
          $dom->preserveWhiteSpace = true;
          $dom->formatOutput = false;
          $dom->loadHTML($html, LIBXML_HTML_NODEFDTD);
          $dom->loadHTML(str_replace("n", "", $dom->saveHTML($dom->getElementsByTagName('body')->item(0))), LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);

          echo $dom->saveHTML();


          DEMO



          Since saveHTML() returns the string, pass the Node to that, then replace the line breaks, then pass that to loadHTML().






          share|improve this answer


















          • 1





            hehe - that is ugly but thanks. at the moment I'm doing this: str_replace(PHP_EOL, '', $dom->saveHTML($dom->getElementsByTagName('body')->item(0))); which I think yields the same result with a bit less effort. I'm still looking for a better method but appreciate your suggestion.

            – billynoah
            Nov 13 '18 at 19:46






          • 1





            Okay. In the future, if you already have a solution, but just don't like it, you should include that in your question.

            – Patrick Q
            Nov 13 '18 at 19:47











          • Agreed Patrick, I actually posted the question before I came up with that workaround and was in the process of editing my question to make that clear when you posted this. That said, I've upvoted your answer and I think it's useful and you probably wouldn't have written it if I'd posted my workaround to begin with - alls well that ends well.

            – billynoah
            Nov 13 '18 at 19:57











          • Yup. I like Nigel's better anyway :)

            – Patrick Q
            Nov 13 '18 at 19:59










          Your Answer






          StackExchange.ifUsing("editor", function ()
          StackExchange.using("externalEditor", function ()
          StackExchange.using("snippets", function ()
          StackExchange.snippets.init();
          );
          );
          , "code-snippets");

          StackExchange.ready(function()
          var channelOptions =
          tags: "".split(" "),
          id: "1"
          ;
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function()
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled)
          StackExchange.using("snippets", function()
          createEditor();
          );

          else
          createEditor();

          );

          function createEditor()
          StackExchange.prepareEditor(
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader:
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          ,
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          );



          );













          draft saved

          draft discarded


















          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53288092%2fhow-to-use-php-domdocument-savehtmlnode-without-added-whitespace%23new-answer', 'question_page');

          );

          Post as a guest















          Required, but never shown

























          3 Answers
          3






          active

          oldest

          votes








          3 Answers
          3






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          3














          If you know your document is going to be valid XML as well, you can use saveXML() instead...



          $html = '<html><body><div>123</div><div>456</div></body></html>';
          $dom = new DOMDocument;
          $dom->preserveWhiteSpace = true;
          $dom->formatOutput = false;
          $dom->loadHTML($html, LIBXML_HTML_NODEFDTD);
          $body = $dom->getElementsByTagName('body')->item(0);
          echo $dom->saveXML($body);


          which gives...



          <body><div>123</div><div>456</div></body>





          share|improve this answer

























          • Looking deeper into this, saveXML() respects the formatOutput property with or without the argument, while saveHTML() only works without argument. Seems like a bug to me. Thanks for the workaround!

            – billynoah
            Nov 13 '18 at 19:54















          3














          If you know your document is going to be valid XML as well, you can use saveXML() instead...



          $html = '<html><body><div>123</div><div>456</div></body></html>';
          $dom = new DOMDocument;
          $dom->preserveWhiteSpace = true;
          $dom->formatOutput = false;
          $dom->loadHTML($html, LIBXML_HTML_NODEFDTD);
          $body = $dom->getElementsByTagName('body')->item(0);
          echo $dom->saveXML($body);


          which gives...



          <body><div>123</div><div>456</div></body>





          share|improve this answer

























          • Looking deeper into this, saveXML() respects the formatOutput property with or without the argument, while saveHTML() only works without argument. Seems like a bug to me. Thanks for the workaround!

            – billynoah
            Nov 13 '18 at 19:54













          3












          3








          3







          If you know your document is going to be valid XML as well, you can use saveXML() instead...



          $html = '<html><body><div>123</div><div>456</div></body></html>';
          $dom = new DOMDocument;
          $dom->preserveWhiteSpace = true;
          $dom->formatOutput = false;
          $dom->loadHTML($html, LIBXML_HTML_NODEFDTD);
          $body = $dom->getElementsByTagName('body')->item(0);
          echo $dom->saveXML($body);


          which gives...



          <body><div>123</div><div>456</div></body>





          share|improve this answer















          If you know your document is going to be valid XML as well, you can use saveXML() instead...



          $html = '<html><body><div>123</div><div>456</div></body></html>';
          $dom = new DOMDocument;
          $dom->preserveWhiteSpace = true;
          $dom->formatOutput = false;
          $dom->loadHTML($html, LIBXML_HTML_NODEFDTD);
          $body = $dom->getElementsByTagName('body')->item(0);
          echo $dom->saveXML($body);


          which gives...



          <body><div>123</div><div>456</div></body>






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 14 '18 at 5:31









          Paul

          17.3k103757




          17.3k103757










          answered Nov 13 '18 at 19:50









          Nigel RenNigel Ren

          26.5k61833




          26.5k61833












          • Looking deeper into this, saveXML() respects the formatOutput property with or without the argument, while saveHTML() only works without argument. Seems like a bug to me. Thanks for the workaround!

            – billynoah
            Nov 13 '18 at 19:54

















          • Looking deeper into this, saveXML() respects the formatOutput property with or without the argument, while saveHTML() only works without argument. Seems like a bug to me. Thanks for the workaround!

            – billynoah
            Nov 13 '18 at 19:54
















          Looking deeper into this, saveXML() respects the formatOutput property with or without the argument, while saveHTML() only works without argument. Seems like a bug to me. Thanks for the workaround!

          – billynoah
          Nov 13 '18 at 19:54





          Looking deeper into this, saveXML() respects the formatOutput property with or without the argument, while saveHTML() only works without argument. Seems like a bug to me. Thanks for the workaround!

          – billynoah
          Nov 13 '18 at 19:54













          5















          Is this a bug?




          Yes, it's a bug and it's reported here




          Is there a workaround?




          Stick with Nigel's solution for now




          Did they fix it?




          Yes, as of 7.3.0 alpha3 this is a fixed bug



          Check it here






          share|improve this answer























          • wow, nice work finding that. thanks for the reference

            – billynoah
            Nov 14 '18 at 0:18















          5















          Is this a bug?




          Yes, it's a bug and it's reported here




          Is there a workaround?




          Stick with Nigel's solution for now




          Did they fix it?




          Yes, as of 7.3.0 alpha3 this is a fixed bug



          Check it here






          share|improve this answer























          • wow, nice work finding that. thanks for the reference

            – billynoah
            Nov 14 '18 at 0:18













          5












          5








          5








          Is this a bug?




          Yes, it's a bug and it's reported here




          Is there a workaround?




          Stick with Nigel's solution for now




          Did they fix it?




          Yes, as of 7.3.0 alpha3 this is a fixed bug



          Check it here






          share|improve this answer














          Is this a bug?




          Yes, it's a bug and it's reported here




          Is there a workaround?




          Stick with Nigel's solution for now




          Did they fix it?




          Yes, as of 7.3.0 alpha3 this is a fixed bug



          Check it here







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 13 '18 at 21:31









          FatalErrorFatalError

          4131311




          4131311












          • wow, nice work finding that. thanks for the reference

            – billynoah
            Nov 14 '18 at 0:18

















          • wow, nice work finding that. thanks for the reference

            – billynoah
            Nov 14 '18 at 0:18
















          wow, nice work finding that. thanks for the reference

          – billynoah
          Nov 14 '18 at 0:18





          wow, nice work finding that. thanks for the reference

          – billynoah
          Nov 14 '18 at 0:18











          2














          Well, it's a pretty ugly workaround, but it gets the job done:



          $html = '<html><body><div>123</div><div>456</div></body></html>';
          $dom = new DOMDocument;
          $dom->preserveWhiteSpace = true;
          $dom->formatOutput = false;
          $dom->loadHTML($html, LIBXML_HTML_NODEFDTD);
          $dom->loadHTML(str_replace("n", "", $dom->saveHTML($dom->getElementsByTagName('body')->item(0))), LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);

          echo $dom->saveHTML();


          DEMO



          Since saveHTML() returns the string, pass the Node to that, then replace the line breaks, then pass that to loadHTML().






          share|improve this answer


















          • 1





            hehe - that is ugly but thanks. at the moment I'm doing this: str_replace(PHP_EOL, '', $dom->saveHTML($dom->getElementsByTagName('body')->item(0))); which I think yields the same result with a bit less effort. I'm still looking for a better method but appreciate your suggestion.

            – billynoah
            Nov 13 '18 at 19:46






          • 1





            Okay. In the future, if you already have a solution, but just don't like it, you should include that in your question.

            – Patrick Q
            Nov 13 '18 at 19:47











          • Agreed Patrick, I actually posted the question before I came up with that workaround and was in the process of editing my question to make that clear when you posted this. That said, I've upvoted your answer and I think it's useful and you probably wouldn't have written it if I'd posted my workaround to begin with - alls well that ends well.

            – billynoah
            Nov 13 '18 at 19:57











          • Yup. I like Nigel's better anyway :)

            – Patrick Q
            Nov 13 '18 at 19:59















          2














          Well, it's a pretty ugly workaround, but it gets the job done:



          $html = '<html><body><div>123</div><div>456</div></body></html>';
          $dom = new DOMDocument;
          $dom->preserveWhiteSpace = true;
          $dom->formatOutput = false;
          $dom->loadHTML($html, LIBXML_HTML_NODEFDTD);
          $dom->loadHTML(str_replace("n", "", $dom->saveHTML($dom->getElementsByTagName('body')->item(0))), LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);

          echo $dom->saveHTML();


          DEMO



          Since saveHTML() returns the string, pass the Node to that, then replace the line breaks, then pass that to loadHTML().






          share|improve this answer


















          • 1





            hehe - that is ugly but thanks. at the moment I'm doing this: str_replace(PHP_EOL, '', $dom->saveHTML($dom->getElementsByTagName('body')->item(0))); which I think yields the same result with a bit less effort. I'm still looking for a better method but appreciate your suggestion.

            – billynoah
            Nov 13 '18 at 19:46






          • 1





            Okay. In the future, if you already have a solution, but just don't like it, you should include that in your question.

            – Patrick Q
            Nov 13 '18 at 19:47











          • Agreed Patrick, I actually posted the question before I came up with that workaround and was in the process of editing my question to make that clear when you posted this. That said, I've upvoted your answer and I think it's useful and you probably wouldn't have written it if I'd posted my workaround to begin with - alls well that ends well.

            – billynoah
            Nov 13 '18 at 19:57











          • Yup. I like Nigel's better anyway :)

            – Patrick Q
            Nov 13 '18 at 19:59













          2












          2








          2







          Well, it's a pretty ugly workaround, but it gets the job done:



          $html = '<html><body><div>123</div><div>456</div></body></html>';
          $dom = new DOMDocument;
          $dom->preserveWhiteSpace = true;
          $dom->formatOutput = false;
          $dom->loadHTML($html, LIBXML_HTML_NODEFDTD);
          $dom->loadHTML(str_replace("n", "", $dom->saveHTML($dom->getElementsByTagName('body')->item(0))), LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);

          echo $dom->saveHTML();


          DEMO



          Since saveHTML() returns the string, pass the Node to that, then replace the line breaks, then pass that to loadHTML().






          share|improve this answer













          Well, it's a pretty ugly workaround, but it gets the job done:



          $html = '<html><body><div>123</div><div>456</div></body></html>';
          $dom = new DOMDocument;
          $dom->preserveWhiteSpace = true;
          $dom->formatOutput = false;
          $dom->loadHTML($html, LIBXML_HTML_NODEFDTD);
          $dom->loadHTML(str_replace("n", "", $dom->saveHTML($dom->getElementsByTagName('body')->item(0))), LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);

          echo $dom->saveHTML();


          DEMO



          Since saveHTML() returns the string, pass the Node to that, then replace the line breaks, then pass that to loadHTML().







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Nov 13 '18 at 19:43









          Patrick QPatrick Q

          5,34421931




          5,34421931







          • 1





            hehe - that is ugly but thanks. at the moment I'm doing this: str_replace(PHP_EOL, '', $dom->saveHTML($dom->getElementsByTagName('body')->item(0))); which I think yields the same result with a bit less effort. I'm still looking for a better method but appreciate your suggestion.

            – billynoah
            Nov 13 '18 at 19:46






          • 1





            Okay. In the future, if you already have a solution, but just don't like it, you should include that in your question.

            – Patrick Q
            Nov 13 '18 at 19:47











          • Agreed Patrick, I actually posted the question before I came up with that workaround and was in the process of editing my question to make that clear when you posted this. That said, I've upvoted your answer and I think it's useful and you probably wouldn't have written it if I'd posted my workaround to begin with - alls well that ends well.

            – billynoah
            Nov 13 '18 at 19:57











          • Yup. I like Nigel's better anyway :)

            – Patrick Q
            Nov 13 '18 at 19:59












          • 1





            hehe - that is ugly but thanks. at the moment I'm doing this: str_replace(PHP_EOL, '', $dom->saveHTML($dom->getElementsByTagName('body')->item(0))); which I think yields the same result with a bit less effort. I'm still looking for a better method but appreciate your suggestion.

            – billynoah
            Nov 13 '18 at 19:46






          • 1





            Okay. In the future, if you already have a solution, but just don't like it, you should include that in your question.

            – Patrick Q
            Nov 13 '18 at 19:47











          • Agreed Patrick, I actually posted the question before I came up with that workaround and was in the process of editing my question to make that clear when you posted this. That said, I've upvoted your answer and I think it's useful and you probably wouldn't have written it if I'd posted my workaround to begin with - alls well that ends well.

            – billynoah
            Nov 13 '18 at 19:57











          • Yup. I like Nigel's better anyway :)

            – Patrick Q
            Nov 13 '18 at 19:59







          1




          1





          hehe - that is ugly but thanks. at the moment I'm doing this: str_replace(PHP_EOL, '', $dom->saveHTML($dom->getElementsByTagName('body')->item(0))); which I think yields the same result with a bit less effort. I'm still looking for a better method but appreciate your suggestion.

          – billynoah
          Nov 13 '18 at 19:46





          hehe - that is ugly but thanks. at the moment I'm doing this: str_replace(PHP_EOL, '', $dom->saveHTML($dom->getElementsByTagName('body')->item(0))); which I think yields the same result with a bit less effort. I'm still looking for a better method but appreciate your suggestion.

          – billynoah
          Nov 13 '18 at 19:46




          1




          1





          Okay. In the future, if you already have a solution, but just don't like it, you should include that in your question.

          – Patrick Q
          Nov 13 '18 at 19:47





          Okay. In the future, if you already have a solution, but just don't like it, you should include that in your question.

          – Patrick Q
          Nov 13 '18 at 19:47













          Agreed Patrick, I actually posted the question before I came up with that workaround and was in the process of editing my question to make that clear when you posted this. That said, I've upvoted your answer and I think it's useful and you probably wouldn't have written it if I'd posted my workaround to begin with - alls well that ends well.

          – billynoah
          Nov 13 '18 at 19:57





          Agreed Patrick, I actually posted the question before I came up with that workaround and was in the process of editing my question to make that clear when you posted this. That said, I've upvoted your answer and I think it's useful and you probably wouldn't have written it if I'd posted my workaround to begin with - alls well that ends well.

          – billynoah
          Nov 13 '18 at 19:57













          Yup. I like Nigel's better anyway :)

          – Patrick Q
          Nov 13 '18 at 19:59





          Yup. I like Nigel's better anyway :)

          – Patrick Q
          Nov 13 '18 at 19:59

















          draft saved

          draft discarded
















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid


          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.

          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53288092%2fhow-to-use-php-domdocument-savehtmlnode-without-added-whitespace%23new-answer', 'question_page');

          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          這個網誌中的熱門文章

          How to read a connectionString WITH PROVIDER in .NET Core?

          Node.js Script on GitHub Pages or Amazon S3

          Museum of Modern and Contemporary Art of Trento and Rovereto