PHP使用名称空间附加XML文档

PHP使用名称空间附加XML文档,php,xml,xpath,Php,Xml,Xpath,我正在尝试用PHP解析docx文件。现在我想附加document.xml文件(这是解压后的docx文件的主要部分)。结构如下: <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <w:document xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas" xmlns:mc="http://schem

我正在尝试用PHP解析docx文件。现在我想附加document.xml文件(这是解压后的docx文件的主要部分)。结构如下:

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <w:document xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"                               xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"             
mc:Ignorable="w14 wp14">
        <w:body>
            <w:p w:rsidR="00080C51" w:rsidRDefault="00080C51">
                <w:pPr>
                    <w:pStyle w:val="a3"/>
                    <w:ind w:left="1020"/>
                    <w:rPr>
                        <w:rFonts w:ascii="Arial" w:hAnsi="Arial" w:cs="Arial"/>
                        <w:sz w:val="22"/>
                        <w:szCs w:val="22"/>
                    </w:rPr>
                </w:pPr>
                <w:bookmarkStart w:id="0" w:name="_GoBack"/>
                <w:bookmarkEnd w:id="0"/>
            </w:p>
            <w:sectPr w:rsidR="00080C51">
                <w:pgSz w:w="11906" w:h="16838"/>
                <w:pgMar w:top="850" w:right="850" w:bottom="850" w:left="1417" w:header="708" w:footer="708" w:gutter="0"/>
                <w:cols w:space="708"/>
                <w:docGrid w:linePitch="360"/>
            </w:sectPr>
        </w:body>
    </w:document>

我想做的是向
标记添加新的子
文本。我该怎么做


在PHP中使用XML文档有很多方法,比如DOM、SimpleXMLElement。但是,哪一个可以帮助我实现这一点呢?

您可以使用SimpleXML按如下方式实现:

$data = simplexml_load_file('test.xml');

$ns = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main'; // the namespace

foreach ($data->children($ns) as $i) {
    // add 'p' element only if the current child name is 'body'
    if ($i->getName() == 'body') {
        $newVal = $i->addChild('p', 'testval'); // add the child
        // only if you want it to have the same attributes as the 'p' element above;
        // otherwise comment out the two lines below
        $newVal->addAttribute('w:rsidR', '00080C51', $ns);
        $newVal->addAttribute('w:rsidRDefault', '00080C51', $ns);
    }
}

print_r($data->asXML());
编辑:

下面是一个使用DOM的版本,它将新元素添加为
w:body
中的第一个元素:

$xmlDoc = new DOMDocument();
$xmlDoc->load("test.xml");

$ns = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main';

$newVal = new DOMElement('p', 'testval', $ns);

foreach ($xmlDoc->childNodes as $i) {
        foreach ($i->childNodes as $j) {
                if($j->localName == 'body') {
                        $j->insertBefore($newVal, $j->firstChild);
                }
        }
}

// add the attributes after the new DOMElement is added
$newVal->setAttributeNS($ns, 'rsidR', '00080C51');
$newVal->setAttributeNS($ns, 'rsidRDefault', '00080C51');

print_r($xmlDoc->saveXML());

看起来很棒。谢谢。但是标记
应该是最后一个,但是现在
的新子项出现在该标记之后。也许我可以删除它并在添加新的
标记后再次添加?现在我对它进行了测试,它似乎起了作用。不幸的是,新的标签属性没有
w:
。@Steve.B我添加了一个带有DOM的版本,它在现有的
w:p
之前添加了新的子项。另外,我忘记了SimpleXML版本中的属性名称空间,所以我也纠正了这一点。我想这几乎就是我需要的。非常感谢你。你能再帮我一点吗?我如何像在第一个解决方案中那样按名称调用元素<代码>$elems=$xml->children($ns);打印($elems->name1->name2)@Steve.B当元素有名称空间时,不能按元素名调用。但是,在本例中,您可以使用
simplexml\u load\u文件('test.xml',“simplexmlement”,null,$ns)然后就可以了。这样,添加新值只需一行:
$data->body->addChild('p','testval')