Viewed   124 times

Is it possible to use PHP's SimpleXML functions to create an XML object from scratch? Looking through the function list, there's ways to import an existing XML string into an object that you can then manipulate, but if I just want to generate an XML object programmatically from scratch, what's the best way to do that?

I figured out that you can use simplexml_load_string() and pass in the root string that you want, and then you've got an object you can manipulate by adding children... although this seems like kind of a hack, since I have to actually hardcode some XML into the string before it can be loaded.

I've done it using the DOMDocument functions, although it's a little confusing because I'm not sure what the DOM has to do with creating a pure XML document... so maybe it's just badly named :-)

 Answers

2

Sure you can. Eg.

<?php
$newsXML = new SimpleXMLElement("<news></news>");
$newsXML->addAttribute('newsPagePrefix', 'value goes here');
$newsIntro = $newsXML->addChild('content');
$newsIntro->addAttribute('type', 'latest');
Header('Content-type: text/xml');
echo $newsXML->asXML();
?>

Output

<?xml version="1.0"?>
<news newsPagePrefix="value goes here">
    <content type="latest"/>
</news>

Have fun.

Saturday, September 10, 2022
3

It seems SimpleXML distinguishes between numeric and non-numeric array offsets in a slightly different way to a normal PHP array, so you need to cast your variable to an integer first. (All input from the query string is a string until you tell PHP otherwise.)

$var = intval($_GET['var']);
echo $xml->foo[$var]->bar;

This will turn the string '1' into the integer 1, and should give the result you require.

Saturday, October 22, 2022
 
vomako
 
5

Set the content type to be XML, so that the browser will recognise it as XML.

header( "content-type: application/xml; charset=ISO-8859-15" );

In your code Change it to:

// Set the content type to be XML, so that the browser will   recognise it as XML.
header( "content-type: application/xml; charset=ISO-8859-15" );

// "Create" the document.
$doc = new DOMDocument( "1.0", "ISO-8859-15" );

+++I think you can do something like this

<root>
<?
   foreach ( $row as $fieldname => $fieldvalue){
    ?>
    <events>
        <fieldname><?=fieldname; ?></fieldname>
        <fieldvalue><?=$fieldvalue; ?></fieldvalue>
    </events>
    }
?>
</root>
Monday, December 19, 2022
 
dan_s
 
4

Using recursion, you can create a brand new document based on the input, solving all your points at once:

Code

<?php

$input = file_get_contents('http://www.fluffyduck.com.au/sampleXML.xml');
$inputDoc = new DOMDocument();
$inputDoc->loadXML($input);

$outputDoc = new DOMDocument("1.0", "utf-8");
$outputDoc->appendChild($outputDoc->createElement("root"));

function ConvertUserToItem($outputDoc, $inputNode, $outputNode)
{
    if ($inputNode->hasChildNodes())
    {
        foreach ($inputNode->childNodes as $inputChild)
        {
            if (strtolower($inputChild->nodeName) == "user")
            {
                $outputChild = $outputDoc->createElement("item");
                $outputNode->appendChild($outputChild);
                // read input attributes and convert them to nodes
                if ($inputChild->hasAttributes())
                {
                    $outputContent = $outputDoc->createElement("content");
                    foreach ($inputChild->attributes as $attribute)
                    {
                        if (strtolower($attribute->name) != "id")
                        {
                            $outputContent->appendChild($outputDoc->createElement($attribute->name, $attribute->value));
                        }
                        else
                        {
                            $outputChild->setAttribute($attribute->name, $attribute->value);
                        }
                    }               
                    $outputChild->appendChild($outputContent);
                }
                // recursive call
                ConvertUserToItem($outputDoc, $inputChild, $outputChild);
            }
        }
    }
}

ConvertUserToItem($outputDoc, $inputDoc->documentElement, $outputDoc->documentElement);

header("Content-Type: text/xml; charset=" . $outputDoc->encoding);
echo $outputDoc->saveXML();
?>

Output

<?xml version="1.0" encoding="utf-8"?>
<root>
    <item id="41">
        <content>
            <username>bsmain</username>
            <firstname>Boss</firstname>
            <lastname>MyTest</lastname>
            <fullname>Test Name</fullname>
            <email>lalal@test.com</email>
            <logins>1964</logins>
            <lastseen>11/09/2012</lastseen>
        </content>
        <item id="61">
            <content>
                <username>underling</username>
                <firstname>Under</firstname>
                <lastname>MyTest</lastname>
                <fullname>Test Name</fullname>
                <email>lalal@test.com</email>
                <logins>4</logins>
                <lastseen>08/09/2009</lastseen>
            </content>
        </item>
...
Friday, December 9, 2022
 
petele
 
2

You want to turn an arbitrary .NET object into a serialized XML string? Nothing simpler than that!! :-)

public string SerializeToXml(object input)
{
   XmlSerializer ser = new XmlSerializer(input.GetType(), "http://schemas.yournamespace.com");
   string result = string.Empty;

   using(MemoryStream memStm = new MemoryStream())
   {
     ser.Serialize(memStm, input);

     memStm.Position = 0;
     result = new StreamReader(memStm).ReadToEnd();
   } 

   return result;
} 

That should to it :-) Of course you might want to make the default XML namespace configurable as a parameter, too.

Or do you want to be able to create an XmlDocument on top of an existing object?

public XmlDocument SerializeToXmlDocument(object input)
{
   XmlSerializer ser = new XmlSerializer(input.GetType(), "http://schemas.yournamespace.com");

   XmlDocument xd = null;

   using(MemoryStream memStm = new MemoryStream())
   {
     ser.Serialize(memStm, input);

     memStm.Position = 0;

     XmlReaderSettings settings = new XmlReaderSettings();
     settings.IgnoreWhitespace = true;

     using(var xtr = XmlReader.Create(memStm, settings))
     {  
        xd = new XmlDocument();
        xd.Load(xtr);
     }
   }

   return xd;
}
Saturday, December 17, 2022
 
Only authorized users can answer the search term. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :