Search code examples
phpxmlvalidationschemaxmlwriter

How to prevent XMLWriter from appending blank line to outputted XML file?


The following code creates an XML file, but the last line is blank which causes problems when validated.

How can I change the following code so that the outputted file does not have a blank line at the end of it?

<?php
$xmlFileName = 'testoutput.xml';

$xml = new XMLWriter;
$xml->openURI($xmlFileName);
$xml->startDocument('1.0', 'UTF-8');
$xml->setIndent(1);

$xml->startElement('name');
$xml->text('jim');
$xml->endElement();

$xml->endDocument();
$xml->flush();      
?>

@DavidRR, the validation problem comes when I validate the XML file with the following code, it tells me that there is "extra content at the end of the document":

$schema = 'test.xsd';
$files[] = 'test1.xml';
$files[] = 'test2.xml';

foreach ($files as $file) {
    validateXml($file, $schema);
}

function validateXml($xmlFile, $xsdFile) {
    $dom = new DOMDocument;
    $dom->load($xmlFile);
    libxml_use_internal_errors(true); // enable user error handling
    echo "Validating <b>$xmlFile</b> with <b>$xsdFile</b>:";
    if ($dom->schemaValidate($xsdFile)) {
        echo '<div style="margin-left:20px">ok</div>';
    } else {
        $errors = libxml_get_errors();
        if (count($errors) > 0) {
            echo '<ul style="color:red">';
            foreach ($errors as $error) {
                //var_dump($error);
                echo '<li>' . $error->message . '</li>';
            }
            echo '</ul>';
        }
        libxml_clear_errors();
        echo '</span>';
        libxml_use_internal_errors(false); // enable user error handling
    }
}   

Solution

  • Reported problem: Because of the presence of a blank line at the end of an XML file, a schema validation attempt on the file results in the error:

    "Extra content at the end of the document"
    

    I'm not able to reproduce your stated problem at codepad, PHP version 5.4-dev, or any of the earlier versions of PHP on that site. I'm including my edited version of your code here as well. (My version includes functions to create the simple XSD and XML files under examination.)

    Possibility: Could your problem be related to the version of PHP that you are using?

    If I haven't accurately tested your scenario with my adaptation of your code, please further modify my code to precipitate the problem.

    <?php
    
    $xsdFile = sys_get_temp_dir() . '/test1.xsd';
    $xmlFile = sys_get_temp_dir() . '/test1.xml';
    
    createXsdFile($xsdFile);
    createXmlFile($xmlFile);
    
    $files[] = $xmlFile;
    
    foreach ($files as $file) {
        validateXml($file, $xsdFile);
    }
    
    function validateXml($xmlFile, $xsdFile) {
        $dom = new DOMDocument;
        $dom->load($xmlFile);
    
        libxml_use_internal_errors(true); // enable user error handling
        echo "Validating <b>$xmlFile</b> with <b>$xsdFile</b>:";
        if ($dom->schemaValidate($xsdFile)) {
            echo '<div style="margin-left:20px">ok</div>';
        } else {
            $errors = libxml_get_errors();
            if (count($errors) > 0) {
                echo '<ul style="color:red">';
                foreach ($errors as $error) {
                    //var_dump($error);
                    echo '<li>' . $error->message . '</li>';
                }
                echo '</ul>';
            }
            libxml_clear_errors();
            echo '</span>';
            libxml_use_internal_errors(false); // enable user error handling
        }
    }
    
    function createXsdFile($xsdFile) {
        $file = fopen($xsdFile, 'w');
        fwrite($file, "<?xml version='1.0' encoding='utf-8'?>\n");
        fwrite($file, "<schema xmlns='http://www.w3.org/2001/XMLSchema'>\n");
        fwrite($file, "<element name='name' type='string' />\n");
        fwrite($file, "</schema>\n");
        fclose($file);
    }
    
    //
    // Appends a blank line at the end of the XML file.
    // Does this cause a schema validation problem?
    //
    function createXmlFile($xmlFile) {
        $xml = new XMLWriter;
        $xml->openURI($xmlFile);
        $xml->startDocument('1.0', 'UTF-8');
        $xml->setIndent(1);
    
        $xml->startElement('name');
        $xml->text('jim');
        $xml->endElement();
    
        $xml->endDocument();
        $xml->flush();
    }
    ?>