简体   繁体   中英

Using PHP to create an XML file

I'm trying to create an XML file using PHP, but I can't get it to run right. I can get the xml to run by itself and the php to run by itself, but I can't get them to run together.

Here is my PHP code:

<?xml version="1.0"?>
<!DOCTYPE squad SYSTEM "squad.dtd">
<?xml-stylesheet href="squad.xsl?" type="text/xsl"?>

<squad nick="MyTAG">
<name>GROUP NAME</name>
<email>admin@website.com</email>
<web>http://website.com/</web>
<picture>Logo.png</picture>
<title>Multi-gaming Team</title>

<?php
mysql_connect("", "", "") or die(mysql_error()); 
mysql_select_db("") or die(mysql_error());

$sql = "SELECT fid37, fid38, fid39 FROM mytable WHERE fid37 IS NOT NULL";
$res = mysql_query($sql);

$xml = new XMLWriter();
$xml->openURI("php://output");
$xml->startDocument();
$xml->setIndent(true);

while ($row = mysql_fetch_assoc($res)) {
  $xml->startElement('member');
  $xml->writeAttribute('id', $row['fid38']);
  $xml->writeAttribute('nick', $row['fid37']);

  $xml->writeElement('name', $row['fid37']);
  $xml->writeElement('email', 'N/A');  
  $xml->writeElement('icq', 'N/A');  
  $xml->writeElement('remark', $row['fid39']);  

$xml->endElement('member');
}

//header('Content-type: text/xml');
$xml->flush();

?>
</squad>

where the output would be

<squad nick="MyTAG">
    <name>GROUP NAME</name>
    <email>admin@website.com</email>
    <web>http://website.com/</web>
    <picture>Logo.png</picture>
    <title>Multi-gaming Team</title>    

    <member id="NUMBER" nick="NAME">
    <name>NAME</name>
    <email>N/A</email>
    <icq>N/A</icq>
    <remark>My REMARK</remark>
    </member>

    <member id="NUMBER" nick="NAME">
    <name>NAME</name>
    <email>N/A</email>
    <icq>N/A</icq>
    <remark>My REMARK</remark>
    </member>
</squad>

Is anyone able to help me correct this?

The biggest problem is in this line:

$xml->endElement('member');

For object oriented style, XMLWriter::endElement expects no arguments. From http://php.net/manual/en/function.xmlwriter-end-element.php :

bool XMLWriter::endElement ( void )

The argument is making endElement fail which is causing the unintended nesting. Remove the parameter and your nesting problem should be solved:

$xml->endElement();

The other problem is that XMLWriter::startDocument will output <?xml version="1.0"?> in the middle of your document which starts before the opening php tag. Instead of mixing raw XML with XMLWriter , have your XMLWriter object handle all of the content.

Try the following modified version of your code:

<?php
//mysql_connect("", "", "") or die(mysql_error()); 
//mysql_select_db("") or die(mysql_error());
//$sql = "SELECT fid37, fid38, fid39 FROM mytable WHERE fid37 IS NOT NULL";
//$res = mysql_query($sql);

$rows = array
(
    array ("fid37" => "1fid37", "fid38" => "1fid38", "fid39" => "1fid39"),
    array ("fid37" => "2fid37", "fid38" => "2fid38", "fid39" => "2fid39"),
    array ("fid37" => "3fid37", "fid38" => "3fid38", "fid39" => "3fid39"),
    array ("fid37" => "4fid37", "fid38" => "4fid38", "fid39" => "4fid39")
);

$xml = new XMLWriter();
$xml->openURI("php://output");
$xml->startDocument();
$xml->setIndent(true);
$xml->writePI('xml-stylesheet', 'href="squad.xsl?" type="text/xsl"');
$xml->writeDTD('squad', null, 'squad.dtd');

$xml->startElement('squad');
$xml->writeAttribute('nick', 'MyTAG');

$xml->writeElement('name', 'GROUP NAME');
$xml->writeElement('email', 'admin@website.com');
$xml->writeElement('web', 'http://website.com/');
$xml->writeElement('picture', 'Logo.png');
$xml->writeElement('title', 'Multi-gaming Team');

//while ($row = mysql_fetch_assoc($res))
foreach ($rows as $row)
{
    $xml->startElement('member');
    $xml->writeAttribute('id', $row['fid38']);
    $xml->writeAttribute('nick', $row['fid37']);

    $xml->writeElement('name', $row['fid37']);
    $xml->writeElement('email', 'N/A');  
    $xml->writeElement('icq', 'N/A');  
    $xml->writeElement('remark', $row['fid39']);  

    $xml->endElement();
}

$xml->endElement();

header('Content-type: text/xml');
$xml->flush();

The code should produce the following XML:

<?xml version="1.0"?>
<?xml-stylesheet href="squad.xsl?" type="text/xsl"?>
<!DOCTYPE squad
SYSTEM "squad.dtd">
<squad nick="MyTAG">
 <name>GROUP NAME</name>
 <email>admin@website.com</email>
 <web>http://website.com/</web>
 <picture>Logo.png</picture>
 <title>Multi-gaming Team</title>
 <member id="1fid38" nick="1fid37">
  <name>1fid37</name>
  <email>N/A</email>
  <icq>N/A</icq>
  <remark>1fid39</remark>
 </member>
 <member id="2fid38" nick="2fid37">
  <name>2fid37</name>
  <email>N/A</email>
  <icq>N/A</icq>
  <remark>2fid39</remark>
 </member>
 <member id="3fid38" nick="3fid37">
  <name>3fid37</name>
  <email>N/A</email>
  <icq>N/A</icq>
  <remark>3fid39</remark>
 </member>
 <member id="4fid38" nick="4fid37">
  <name>4fid37</name>
  <email>N/A</email>
  <icq>N/A</icq>
  <remark>4fid39</remark>
 </member>
</squad>

The problem is that your script doesn't do anything with the XML code you've posted at the top of it. You need to output that using XMLWriter -- you can't just add the XML to the script as you've done.

Your script should look something like this (I've omitted some of the details--you can fill them in at your leisure!):

<?php

## these should be changed to mysqli_* functions!
mysql_connect("", "", "") or die(mysql_error()); 
mysql_select_db("") or die(mysql_error());
$sql = "SELECT fid37, fid38, fid39 FROM mytable WHERE fid37 IS NOT NULL";
$res = mysql_query($sql);

# open the XML document
$xml = new XMLWriter();
$xml->openURI("php://output");
$xml->setIndent(true);

$xml->startDocument('1.0');

# writes the DTD line
$xml->writeDTD('squad', NULL, 'squad.dtd');

# writes the stylesheet line
$xml->writePI('xsl-stylesheet', 'href="squad.xsl?" type="text/xsl"');

# now output the squad element and its child nodes
$xml->startElement("squad");
$xml->writeAttribute('nick', 'MYTAG');
$xml->writeElement('name', 'GROUP NAME');
... # etc. for the rest of the elements

# add the members    
while ($row = mysql_fetch_assoc($res)) {
  $xml->startElement('member');
  $xml->writeAttribute('id', $row['fid38']);
  ... # etc.
  # close the member element
  $xml->endElement();
}
# close the squad element and the document
$xml->endElement();
$xml->endDocument();

this is what i ended up using (Starson Hochschild's code with a small edit):

$sql = "SELECT * FROM mytable WHERE `fid37` IS NOT NULL";
$res = mysql_query($sql);




$xml = new XMLWriter();
$xml->openURI("php://output");
$xml->startDocument();
$xml->setIndent(true);
$xml->writePI('xml-stylesheet', 'href="squad.xsl?" type="text/xsl"');
$xml->writeDTD('squad', null, 'squad.dtd');

$xml->startElement('squad');
$xml->writeAttribute('nick', 'MyTag');

$xml->writeElement('name', 'GroupName');
$xml->writeElement('email', 'GroupEmail');
$xml->writeElement('web', 'GroupWebsite');
$xml->writeElement('picture', 'GroupLogo.png');
$xml->writeElement('title', 'Multi-gaming Team');

while ($row = mysql_fetch_assoc($res))
//foreach ($rows as $row)
{
    $xml->startElement('member');
    $xml->writeAttribute('id', $row['fid38']);
    $xml->writeAttribute('nick', $row['fid37']);

    $xml->writeElement('name', $row['fid37']);
    $xml->writeElement('email', 'N/A');  
    $xml->writeElement('icq', 'N/A');  
    $xml->writeElement('remark', $row['fid39']);  

    $xml->endElement();
}

$xml->endElement();

header('Content-type: text/xml');
$xml->flush();

?>

it looks and whats just how it would if I were to actually write the xml code.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM