2015-05-09 3 views
1

Я пытаюсь разобрать файлы docx на PHP. Теперь я хочу добавить файл document.xml (это основная часть распакованного файла docx). Структура:PHP Добавить XML-документ с пространствами имен

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

То, что я хочу сделать, это добавить новый ребенок <w:p>some text</w:p> тег в <w:body> тег. Как я могу это сделать?

Существует множество способов работы с XML-документами на PHP, например DOM, SimpleXMLElement. Но какой из них может помочь мне достичь этого?

ответ

1

Вы можете сделать это следующим образом с 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()); 

EDIT:

Вот версия с использованием 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()); 
+0

Выглядит отлично. Большое спасибо. Но теги ' ...' должны быть последними, но теперь новый тег '' появляется после этого тега. Может быть, я смогу удалить его и добавить снова после добавления нового тега ''? Теперь я тестировал его и, похоже, работал. – Daria

+0

И, к сожалению, новые атрибуты тегов идут без 'w:' .. – Daria

+1

@ Steve.B Я добавил версию с DOM, которая добавляет новый дочерний элемент до существующего 'w: p'. Кроме того, я забыл пространство имен атрибутов в версии SimpleXML, поэтому я также исправил это. – VolenD

Смежные вопросы