Search code examples
phpxmlnamespacessimplexmlparent

How to add XML namespaces to parent elements in PHP


I want to add namespaces to specific parent (and child) elements in my XML, so it looks something like this:

<list xmlns:base="http://schemas.example.com/base">

   <base:customer>
      <base:name>John Doe 1</base:name>
      <base:address>Example 1</base:address>
      <base:taxnumber>10000000-000-00</base:taxnumber>
   </base:customer>

   <product>
      <name>Something</name>
      <price>45.00</price>
   </product>

</list>

I can't figure out how to add the base namespace to the customer parent element.

This is my code so far:

header("Content-Type: application/xml");

$xml_string  = "<list xmlns:base='http://schemas.example.com/base'/>";

$xml = simplexml_load_string($xml_string);

$xml->addChild("customer");

$xml->customer->addChild("name", "John Doe 1", "http://schemas.example.com/base");
$xml->customer->addChild("address", "Example 1", "http://schemas.example.com/base");
$xml->customer->addChild("taxnumber", "10000000-000-00", "http://schemas.example.com/base");

$xml->addChild("product");

$xml->product->addChild("name", "Something");
$xml->product->addChild("price", "45.00");

print $xml->saveXML();

With this, the only thing missing is the base namepace for the customer element.


Solution

  • Two ways:

    1. Use it as the default namespace

    <list xmlns="http://schemas.example.com/base">

    1. Add the prefix to the element

    <base:list xmlns:base="http://schemas.example.com/base">

    However this might result in a different syntax for accessing the elements. The easy way around this is to to store the created elements into variables.

    $xmlns_base = "http://schemas.example.com/base";
    
    $xml_string  = "<base:list xmlns:base='http://schemas.example.com/base'/>";
    
    $xml = simplexml_load_string($xml_string);
    
    $customer = $xml->addChild("base:customer", NULL, $xmlns_base);
    
    $customer->addChild("base:name", "John Doe 1", $xmlns_base);
    $customer->addChild("base:address", "Example 1", $xmlns_base);
    $customer->addChild("base:taxnumber", "10000000-000-00", $xmlns_base);
    
    // provide the empty namespace so it does not get added to the other namespace
    $product = $xml->addChild("product", "", "");
    
    $product->addChild("name", "Something");
    $product->addChild("price", "45.00");
    
    print $xml->saveXML();