1

I'm trying to create an XML like this from a html form using php. I want to create complex element

<recipe>
<portion_size>
<portion_num>
</portion_num>
</portion_size>

<recipe_description>
<prep_time>
</prep_time
<recipe descrip>
</recipe descrip>
<recipe_description>

Something along the lines of that, however i cant seem to nest it properly using the DOM here is my php code. Does anyone have any advice?

$doc = new DOMDocument(); //open the object xml 
    $r = $doc->createElement("recipe"); 
    $doc->appendChild($r); 

    $name = $doc->createElement('name',$name);
    $r->appendChild($name); 

    $r = $doc->createElement("portion_size");
    $doc->appendChild($r);

    $child = $doc->createElement('portion_num',$portionNum);
    $r->appendchild($child);

     $prepTime = $doc->createElement('prep_time',$prepTime);
    $r->appendChild($prepTime);

     $recipeDescrip = $doc->createElement('descrip',$recipeDescrip);
    $r->appendChild($recipeDescrip);

     $utensilNum = $doc->createElement('utensil_num',$utensilNum);
    $r->appendChild($utensilNum);

     $utensilDescrip = $doc->createElement('utensil_descrip',$utensilDescrip);
    $r->appendChild($utensilDescrip);

     $quantityAmount = $doc->createElement('quantity_amount',$quantityAmount);
    $r->appendChild($quantityAmount); 

     $ingredientName = $doc->createElement('ingredient_name',$ingredientName);
    $r->appendChild($ingredientName); 

     $stepNum = $doc->createElement('step_num',$stepNum);
    $r->appendChild($stepNum); 

     $stepDetail = $doc->createElement('step_detail',$stepDetail);
    $r->appendChild($stepDetail); 
3
  • i thought it worked for my portion size, however it doesnt close it off after portion_num it closes it at the end of the xml Commented Nov 25, 2013 at 21:30
  • Creating xml with nothing but DOM is "the correct way", but it's also ludicriously painful. You might be better off just building it all as a giant string, $xml = "<recipe><foo><bar /></foo></recipe"; and getting on with more important things. Commented Nov 25, 2013 at 21:41
  • This can end in a lot of more work. You have to take care of the escaping and make sure that the xml is wellformed. Commented Nov 25, 2013 at 22:22

1 Answer 1

2

You should not use the second argument of DOMDocument::createElement(), it is not part of the w3c dom api and seems broken. You need to use DOMDocument::createTextNode(). However that gets a little noisy, so I suggest you encapsulate the job into a method.

class MyDOMElement extends DOMElement {

  public function appendElement($name, array $attributes = NULL, $content = '') {
    $node = $this->ownerDocument->createElement($name);
    if (!empty($attributes)) {
      foreach ($attributes as $key => $value) {
        $node->setAttribute($key, $value);
      }
    }
    if (!empty($content)) {
      $node->appendChild($this->ownerDocument->createTextNode($content));
    }
    $this->appendChild($node);
    return $node;
  }
}

class MyDOMDocument extends DOMDocument {

  public function __construct($version = '1.0', $encoding= 'utf-8') {
    parent::__construct($version, $encoding);
    $this->registerNodeClass('DOMElement', 'MyDOMElement');
  }
}

$dom = new MyDOMDocument();
$dom->appendChild($root = $dom->createElement('recipe'));

$root->appendElement('name', NULL, 'Reciepe Example');
$root
  ->appendElement('portion_size')
  ->appendElement('portion_num', NULL, '4');
$description = $root->appendElement('recipe_description');
$description->appendElement('prep_time', array('unit' => 'minutes'), '10');
//...

echo $dom->saveXml();

Output:

<?xml version="1.0" encoding="utf-8"?>
<recipe>
  <name>Reciepe Example</name>
  <portion_size>
    <portion_num>4</portion_num>
  </portion_size>
  <recipe_description>
    <prep_time unit="minutes">10</prep_time>
  </recipe_description>
</recipe>
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.