如何获取,编辑和保存包含嵌套命名空间的xml内容?

时间:2013-02-28 07:48:31

标签: xml xpath xml-parsing simplexml domdocument

这是我的xml文件内容:

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<w:document xmlns:ve="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml">
    <w:body>
        <w:p w:rsidR="00551371" w:rsidRDefault="0010551B" w:rsidP="0010551B">
            <w:pPr>
                <w:jc w:val="center"/>
            </w:pPr>
            <w:r>
                <w:t xml:space="preserve">Hi this is a paragraph with </w:t>
            </w:r>
            <w:r w:rsidRPr="00517389">
                <w:rPr>
                    <w:b/>
                </w:rPr>
                <w:t>default</w:t>
            </w:r>
            <w:r>
                <w:t xml:space="preserve"> text and some wording in it so </w:t>
            </w:r>
        </w:p>
        <w:p w:rsidR="0010551B" w:rsidRDefault="0010551B" w:rsidP="0010551B">
            <w:pPr>
                <w:jc w:val="center"/>
            </w:pPr>
            <w:r>
                <w:t xml:space="preserve">Here is new </w:t>
            </w:r>
            <w:r w:rsidRPr="00517389">
                <w:rPr>
                    <w:u w:val="single"/>
                </w:rPr>
                <w:t>line sentence</w:t>
            </w:r>
            <w:r>
                <w:t xml:space="preserve"> with some text.</w:t>
            </w:r>
        </w:p>
          .
          .
          .
          and so on.

现在我独立获得<w:t>的内容,下面是我的代码:

// load the xml into the object
$xml = simplexml_load_file('sample/word/document.xml');

//Use that namespace
$namespaces = $xml->getNameSpaces(true);

$xml->registerXPathNamespace('w', $namespaces['w']);

$nodes = $xml->xpath('/w:document/w:body//w:t');

$i = 1;

foreach ($nodes as $node) {
    echo (string) $node; // prints each node value correctly
    $node->nodeValue = "abc"; // it adds the node instead of replacing
    $i++;
}

$xml->asXML('test.xml');

它分别为我提供了每个w:t的文字,但我希望wrt <w:p>表示单<w:t>下所有<W:p>个节点中的所有文字都应视为单节点。

首先<w:p>下的文字应该返回“嗨这是一个带有默认文字的段落,其中包含一些措辞”。

1 个答案:

答案 0 :(得分:1)

首先,您可以使用registerXPathNamespace方法选择命名空间并使用常规的SimpleXML访问方法,而不是使用->children()和XPath。在这种情况下,您可以使用foreach ( $xml->children('w', true)->body->p as $p_node ) ...

其次,SimpleXML中没有nodeValue属性(也许您正在考虑DOM?)。要覆盖元素的内容,您只需分配给它,例如$node->child = 'abc';。然而,这在循环中有点棘手,因为你必须知道你正在看哪个元素;但你可以说,$xml->children('w', true)->body->p[0] = 'asd';

最后,要合并<w:p>个节点中的所有文字,您需要遍历他们的<w:r>个孩子,在您的示例中,每个孩子都有一个<w:t>。所以你最终会得到一个这样的嵌套循环:

foreach ( $sx->children('w', true)->body->p as $p_node ) { 
    $p_content=''; 
    foreach ( $p_node->r as $r_node ) { 
        $p_content .= (string)$r_node->t; 
    } 
    echo $p_content;
}