Skip to content

Commit

Permalink
[BUGFIX] Ensure nested w:sdt -> w:sdtContent node paresing for Docu…
Browse files Browse the repository at this point in the history
…ment

Nodes can be nested or directly provided for the document structure.
Until now, the `sdt->sdtContent` wrapping have not been respected.

This change moves the node parsing for a document to a dedicated
method and make it recursivly callable to unnest the wrapped node.
  • Loading branch information
sbuerk committed Apr 2, 2024
1 parent 8b891bb commit ae823f1
Showing 1 changed file with 24 additions and 5 deletions.
29 changes: 24 additions & 5 deletions src/PhpWord/Reader/Word2007/Document.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
namespace PhpOffice\PhpWord\Reader\Word2007;

use DOMElement;
use DOMNode;
use PhpOffice\PhpWord\Element\Section;
use PhpOffice\PhpWord\PhpWord;
use PhpOffice\PhpWord\Shared\XMLReader;
Expand Down Expand Up @@ -46,15 +47,33 @@ public function read(PhpWord $phpWord): void
$this->phpWord = $phpWord;
$xmlReader = new XMLReader();
$xmlReader->getDomFromZip($this->docFile, $this->xmlFile);
$readMethods = ['w:p' => 'readWPNode', 'w:tbl' => 'readTable', 'w:sectPr' => 'readWSectPrNode'];

$nodes = $xmlReader->getElements('w:body/*');
if ($nodes->length > 0) {
$section = $this->phpWord->addSection();
foreach ($nodes as $node) {
if (isset($readMethods[$node->nodeName])) {
$readMethod = $readMethods[$node->nodeName];
$this->$readMethod($xmlReader, $node, $section);
$this->readNode($phpWord, $xmlReader, $node, $section);
}
}
}

private function readNode(PhpWord $phpWord, XMLReader $xmlReader, DOMNode $node, Section $section): void
{
$readMethods = ['w:p' => 'readWPNode', 'w:tbl' => 'readTable', 'w:sectPr' => 'readWSectPrNode'];
if (isset($readMethods[$node->nodeName])) {
$readMethod = $readMethods[$node->nodeName];
$this->$readMethod($xmlReader, $node, $section);
} elseif ($node->nodeName === 'w:sdt' && $node instanceof DOMElement) {
$nodes = $xmlReader->getElements('w:sdtContent/*', $node);
if ($nodes->length > 0) {
foreach ($nodes as $subNode) {
$this->readNode($phpWord, $xmlReader, $subNode, $section);
}
}
} elseif ($node->nodeName === 'w:sdtContent' && $node instanceof DOMElement) {
$nodes = $xmlReader->getElements('*', $node);
if ($nodes->length > 0) {
foreach ($nodes as $subNode) {
$this->readNode($phpWord, $xmlReader, $subNode, $section);
}
}
}
Expand Down

0 comments on commit ae823f1

Please sign in to comment.