使用DOMDocument创建复杂的结构

时间:2011-07-16 11:41:46

标签: php xml dom xpath

使用PHP和Dom Document创建复杂的XML结构时遇到了一些问题。

我希望结构如下:

<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>

我到目前为止的代码是

<?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();
?>  

创造的是:

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

仅编辑第一个问题...

我该如何解决这个问题?

4 个答案:

答案 0 :(得分:6)

您的代码看起来比它需要的更复杂。

因为appendChild返回附加节点而setAttribute返回设置的属性节点,所以你也可以创建整个树而不需要任何临时变量,也可以通过链接方法调用和遍历DOM来创建没有任何Xpath的整个树树:

$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();

在想要使用DOM时,了解DOM是DOMNode的树层次结构是必不可少的。有关此问题的解释,请参阅DOMDocument in php

答案 1 :(得分:1)

    $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

答案 2 :(得分:0)

<?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();
?>  

答案 3 :(得分:0)

这可以帮助您解决问题并使代码更紧凑,更易于处理:

appendChild PHP Manual返回新节点。然后,您可以直接使用它。在附加子进程后,无需使用xpath。

如果在将元素节点添加到文档之前添加/设置要设置的属性,则通常甚至不需要:

/*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);

...

对于文档的根元素(<page>),它们完全相同。您不需要使用xpath来访问它并对其进行操作。这是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);