【问题标题】:PHP How To Insert Nested Elements Libreoffice StylePHP 如何插入嵌套元素 Libreoffice 样式
【发布时间】:2018-12-23 10:00:51
【问题描述】:

Libreoffice 将 Writer 文档内容存储在 XML 格式的文件中。在 PHP 中,我想将具有不同格式的文本插入到文本段落中。不幸的是,Libreoffice 在另一个元素的文本中使用嵌套元素来做到这一点。这是一个简化的示例:

<text:p text:style-name="P1">

   the quick brown
        <text:span text:style-name="T1"> fox jumps over</text:span>      
   the lazy dog

</text:p>

我没有发现 PHP 中的 SimpleXML 或 XML DOM 函数可以让我在另一个元素的文本中插入一个新元素,就像这里需要的那样。我在这里忽略了什么吗?

【问题讨论】:

    标签: php xml nested attributes libreoffice


    【解决方案1】:

    SimpleXML 不能很好地处理混合子节点,但在 DOM 中并不难,只是有点冗长。请记住,在 DOM 中,任何东西都是节点,而不仅仅是元素。因此,您要做的是用三个新节点替换单个文本节点 - 一个文本节点、新元素节点和另一个文本节点。

    $xmlns = [
      'text' => 'urn:oasis:names:tc:opendocument:xmlns:text:1.0'
    ];
    
    $xml = <<<'XML'
    <text:p 
       text:style-name="P1" 
       xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0">
       the quick brown fox jumps over the lazy dog
    </text:p>
    XML;
    
    $document = new DOMDocument();
    $document->loadXML($xml);
    $xpath = new DOMXpath($document);
    
    $searchFor = 'fox jumps over';
    
    // iterate over text nodes containing the search string
    $expression = '//text:p//text()[contains(., "'.$searchFor.'")]';
    foreach ($xpath->evaluate($expression) as $textNode) {
        // split the text content at the search string and capture any part
        $parts = preg_split(
            '(('.preg_quote($searchFor).'))', 
            $textNode->textContent, 
            -1, 
            PREG_SPLIT_DELIM_CAPTURE
        );
        // here should be at least two parts
        if (count($parts) < 2) {
            continue;
        }
        // fragments allow to treat several nodes like one
        $fragment = $document->createDocumentFragment();
        foreach ($parts as $part) {
            // matched the text
            if ($part === $searchFor) {
                // create the new span
                $fragment->appendChild(
                    $span = $document->createElementNS($xmlns['text'], 'text:span')
                );
                $span->setAttributeNS($xmlns['text'], 'text:style-name', 'T1');
                $span->appendChild($document->createTextNode($part));
            } else {
                // add the part as a new text node
                $fragment->appendChild($document->createTextNode($part));
            }   
        }
        // replace the text node with the fragment
        $textNode->parentNode->replaceChild($fragment, $textNode);
    }
    
    echo $document->saveXML();
    

    【讨论】:

    • 刚刚试一试,它就像一个魅力!现在到了很难理解细节的部分!非常感谢!!!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多