2013-02-28 2 views
0

Вот мое содержание XML-файла:Как получить, отредактировать и сохранить содержимое 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 отдельно, но я хотите получить по адресу <w:p> означает весь текст всего <w:t> узлов под одним <W:p> следует рассматривать как единый узел.

Как и текст в начале <w:p> должен возвращать «Привет, это абзац с текстом по умолчанию и некоторыми формулировками в нем так».

ответ

1

Во-первых, вместо использования registerXPathNamespace и XPath вы можете просто использовать метод ->children(), чтобы выбрать пространство имен и использовать обычные методы доступа SimpleXML. В этом случае вы можете использовать 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; 
}