Domanda

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
    }
}   
È stato utile?

Soluzione

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

Altri suggerimenti

I have found no way to change the behavior of XmlWriter in that regard. A possible fix would be to read the file, trim it and then write it back to file, e.g.

file_put_contents($xmlFileName, trim(file_get_contents($xmlFileName)));

demo

An alternative would be to ftruncate the file

ftruncate(fopen($xmlFileName, 'r+'), filesize($xmlFileName) - strlen(PHP_EOL));

demo

The latter assumes there will be a platform dependent newline in the file. If there isn't, this will likely break the file then. The trim version is more solid in that regard as it will not damage the file if there isnt a newline, but it has to read the entire file into memory in order to trim the content.

If you are on linux/unix system, you can do:

$test = `head -n -1 < $xmlFileName > $xmlFileName`;

See this.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top