开发者

Create a complex structure with DOMDocument

I have a little problem with creating an complex XML structure with PHP and Dom Document.

I want the structure to be like this:

<page PathToWeb="www.mysite.com">
    <Questions>
        <Question id="my id" member="true">
        <Question id="my id2" member="true">
        <Question id="my id3" member="true">
    </Questions>
</page>

and the code i have so far is

<?php
/*Create DOM*/
$xml = new DOMDocument;
$xml->load('myxml.xml'); /* wich is just just blank <?xml?\> <page> </page>*/
$xpath = new DOMXPath($xml);

/*Set the base path*/
$hrefs = $xpath->evaluate("/page");

/*Add Path to web to the root /page*/
$href = 开发者_开发问答$hrefs->item(0);
$href->setAttribute("PathToWeb",$PathToWeb);


/*Complex XML Creation with Xpath*/

/*ELEMENT APPEND (create questions into /page)*/
$href = $hrefs->item(0);
$element = $xml->createElement('Questions');
$href->appendChild($element);

/*XPATH EVALUATE*/
$hrefs = $xpath->evaluate("/page/Questions");

/*ELEMENT 1 APPEND*/
$href = $hrefs->item(0);
$element = $xml->createElement('Question');
$href->appendChild($element);
$hrefs = $xpath->evaluate("/page/Questions/Question");
$href = $hrefs->item(0);
$href->setAttribute("id","my id");

/*ELEMENT 2 APPEND*/
$href = $hrefs->item(0);
$element = $xml->createElement('Question');
$href->appendChild($element);
$hrefs = $xpath->evaluate("/page/Questions/Question");
$href = $hrefs->item(0);
$href->setAttribute("id","my id");

/*ELEMENT 3 APPEND*/
$href = $hrefs->item(0);
$element = $xml->createElement('Question');
$href->appendChild($element);
$hrefs = $xpath->evaluate("/page/Questions/Question");
$href = $hrefs->item(0);
$href->setAttribute("id","my id");

$href = $hrefs->item(0);
$href->setAttribute("member","true");

$string2 = $xml->saveXML();
?>  

What is creating is:

<page PathToWeb="www.mysite.com">
<Questions><Question id="my id" member="true"><Question/></Question></Questions>
</page>

Editing only the first Question ...

How can i solve this?


Your code looks somewhat more complicated than it needs to be.

Because appendChild returns the appended node and setAttribute returns the set Attribute Node, you could also create the entire tree without any temp variables and also without any Xpath simply by chaining method calls and traversing the DOM tree:

$dom = new DOMDocument('1.0', 'utf-8');
$dom->appendChild($dom->createElement('page'))
    ->setAttribute('PathToWeb', 'www.mysite.com')
        ->parentNode
    ->appendChild($dom->createElement('Questions'))
        ->appendChild($dom->createElement('Question'))
            ->setAttribute('id', 'my_id')
                ->parentNode
            ->setAttribute('member', 'true')
                ->parentNode
            ->parentNode
        ->appendChild($dom->createElement('Question'))
            ->setAttribute('id', 'my_id2')
                ->parentNode
            ->setAttribute('member', 'true')
                ->parentNode
            ->parentNode
    ->appendChild($dom->createElement('Question'))
            ->setAttribute('id', 'my_id3')
                ->parentNode
            ->setAttribute('member', 'true');

$dom->formatOutput = true;
echo $dom->saveXml();

Understanding that DOM is a tree hierarchy of DOMNodes is essential when wanting to work with DOM. See DOMDocument in php for some explanation on that.


    $xml = new DOMDocument('1.0','UTF-8');
    $root = $xml->createElement('page');
    $root->setAttribute("PathToWeb",$PathToWeb);
    $wrap = $xml->createElement('Questions');
    $root->appendChild($wrap);
    for ($i = 1;$i<4;$i++)
    {
    $element = $xml->createElement('question');
    $element->setAttribute("id","my id" . $i);
    $element->setAttribute("member","true");
    $wrap->appendChild($element);
    }
    $xml->appendChild($root);
    $xml->formatOutput = true;
    $xml->save('myxml.xml');// Thanks to Gordon


<?php
$xml = new DOMDocument;
$xml->load('myxml.xml'); /* wich is just just blank <?xml?> <page> </page>*/
$xpath = new DOMXPath($xml);

/*Set the base path*/
$base = $xpath->evaluate("/page")->item(0);

$base->setAttrubute("PathToWeb", $PathToWeb);

$questions = $xml->createElement('Questions');
$base->appendChild($questions);

for($i = 0; $i < 2; $i++) {
    $question= $xml->createElement('Question');
    $questions->appendChild($question);
    $question->setAttribute("id","my id");
    $question->setAttribute("member", "true");
}

$string2 = $xml->saveXML();
?>  


This might help you to solve your problem and make your code much more compact and easier to deal with:

appendChild PHP Manual returns the new node. You can then directly work with it. No need to use xpath after appending the child to get access to it.

And if you add/set the attributes you want to set before adding the element node to the document, you most often don't even need to:

/*ELEMENT APPEND (create questions into /page)*/
$href = $hrefs->item(0);
$element = $xml->createElement('Questions');
$questions = $href->appendChild($element);
#   ^^^


/*ELEMENT 1 APPEND*/
$element = $xml->createElement('Question');
$element->setAttribute("id","my id"); # prepare before adding
$questions->appendChild($element);

...

It's quite the same for the root element of your document (<page>). You do not need to use xpath to access it and manipulate it. It's documentElement PHP Manual:

/*Create DOM*/
$xml = new DOMDocument;
$xml->load('myxml.xml'); /* wich is just just blank <?xml?> <page> </page>*/

/*Add Path to web to the root /page*/
$href = $xml->documentElement;
$href->setAttribute("PathToWeb",$PathToWeb);
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜