3

In my website I put out a lot of internal tracing information for development testing. The content of the trace is formatted for HTML which is fine most of the time, but in order to support AJAX sometimes I want to include that trace data in an XML document. Occasionally XML objects that there are unmatched tags, but it only reports the location in the document where the end tag is missing. These trace documents are typically 10,000 lines long and are generated by code all over the system, so debugging the debugging information is non-trivial. In my current problem the XML parse reported that I was missing a closing </p>.

So I added:

libxml_use_internal_errors(true);

$doc = simplexml_load_string($warn);
$xml = explode("\n", $warn);

if (!$doc) {
    $errors = libxml_get_errors();

    foreach ($errors as $error) {
        echo display_xml_error($error, $xml);
    }

    libxml_clear_errors();
} 

to the spot where the trace data is sent to stdout. Now I get:

<p>User::__construct(Array
-^
Fatal Error 5: Extra content at the end of the document
  Line: 2
  Column: 1

--------------------------------------------

    <div id='debugTrace' class='warning'>
      <p>connection established to database server 'mysql:...'.</p>
    <p>User::__construct(Array
    (
    [username] => jcobban
)
)</p>
<p>SELECT * FROM Users WHERE UserName='jcobban'</p><p class='label'>User Record constructed:</p>
... for 9997 more lines

The <div> is used to enclose all of the trace output with the class styling the output in dark yellow.

Both the XML parser in Firefox and PHP simple XML agree that there is a missing closing </p>, but I see the closing tag in the resulting document, as displayed when I ask XML to display the page source. The line of code that emits the apparently offending line is:

    $warn   .= "<p>User::__construct(" . print_r($parms, true) . 
           ")</p>\n";

So what am I doing wrong?

James Cobban
  • 387
  • 1
  • 2
  • 13

2 Answers2

2

CDATA allows you to render characters into an xml document that would otherwise break it.

$warn   .= "<p><![cdata[User::__construct(" . print_r($parms, true) . 
       ")]]></p>\n";

More info in this very informative item here on SO: What does <![CDATA[]]> in XML mean?

Mouser
  • 13,132
  • 3
  • 28
  • 54
  • Thank you, but I **want** the HTML to be treated as part of the XML document. Although I am targeting HTML5 I am also trying to conform as much as possible to XHTML. If I make this a CDATA then it will be rendered as a huge block of text that will be much harder to interpret visually than when it is rendered as XML. I just want to understand why all of the tools insist that the second

    is unmatched when the closing tag is clearly there and even highlighted by XML viewers and editors.

    – James Cobban Oct 31 '17 at 21:28
0

When I was able to generate the error with a much smaller diagnostic I realized the problem was that I was not supplying a root tag.

$doc = simplexml_load_string($warn); // this fails
$doc = simplexml_load_string('<div>' . $warn . '</div>'); // this works
James Cobban
  • 387
  • 1
  • 2
  • 13