0

首先,我使用的是 Laravel,这就是为什么return在代码末尾有但它实际上不会影响任何东西

$strxml = '<?xml version="1.0" encoding="utf-8" ?>
            <xliff>
                <body>
                    <trans-unit id="NFDBB2FA9-tu4" xml:space="preserve">
                        <source xml:lang="en">He</source>
                        <target xml:lang="id">He</target>
                    </trans-unit>
                    <trans-unit id="NFDBB2FA9-tu5" xml:space="preserve">
                        <source xml:lang="en">She</source>
                        <target xml:lang="id">She</target>
                    </trans-unit>
                </body>
                <body>
                    <trans-unit id="NFDBB2FA9-tu6" xml:space="preserve">
                        <source xml:lang="en">They</source>
                        <target xml:lang="id">They</target>
                    </trans-unit>
                    <trans-unit id="NFDBB2FA9-tu7" xml:space="preserve">
                        <source xml:lang="en">We</source>
                        <target xml:lang="id">We</target>
                    </trans-unit>
                </body>
            </xliff>';

        $dom = new \DOMDocument;
        $dom->loadXML($strxml);

        $xp = new \DOMXPath($dom);
        $xp->registerNamespace('xml', 'http://www.example.com');

        $col = $xp->query('//xliff/body/trans-unit');
        if ($col && $col->length) {
            foreach ($col as $node) {
                $target = $xp->query('target', $node)->item(0);
                $target->nodeValue = '<mrk id="1">Banana';
            }
        }

        return $dom->saveXML();

它输出:

<?xml version="1.0" encoding="utf-8" ?>
<xliff>
    <body>
        <trans-unit id="NFDBB2FA9-tu4" xml:space="preserve">
            <source xml:lang="en">He</source>
            <target xml:lang="id">&lt;mrk id="1"&gt;Banana</target>
        </trans-unit>
        <trans-unit id="NFDBB2FA9-tu5" xml:space="preserve">
            <source xml:lang="en">She</source>
            <target xml:lang="id">&lt;mrk id="1"&gt;Banana</target>
        </trans-unit>
    </body>
    <body>
        <trans-unit id="NFDBB2FA9-tu6" xml:space="preserve">
            <source xml:lang="en">They</source>
            <target xml:lang="id">&lt;mrk id="1"&gt;Banana</target>
        </trans-unit>
        <trans-unit id="NFDBB2FA9-tu7" xml:space="preserve">
            <source xml:lang="en">We</source>
            <target xml:lang="id">&lt;mrk id="1"&gt;Banana</target>
        </trans-unit>
    </body>
</xliff>

<target>注意文字上有特殊字符

已经这样做$target->nodeValue = html_entity_decode('<mrk id="1">Banana');但没有工作

我该如何编码?

4

1 回答 1

-2

DOMNode::nodeValue写时做了一个奇怪的半转义 -DOMNode::$textContent用于文本:

$document = new DOMDocument();
$document
  ->appendChild($document->createElement('demo'))
  ->textContent = '<mrk id="1">foo & bar';
echo $document->saveXML();

输出:

<?xml version="1.0"?>
<demo>&lt;mrk id="1"&gt;foo &amp; bar</demo>

对于 XML 片段,请使用DOMDocumentFragment. 在这种情况下,您的内容必须是有效的 XML。标签必须关闭。

$document = new DOMDocument();
$document
  ->appendChild($document->createElement('demo'));

$fragment = $document->createDocumentFragment();
$fragment->appendXML('<mrk id="1"/>foo &amp; bar');    
$document->documentElement->appendChild($fragment);

echo $document->saveXML();

输出:

<?xml version="1.0"?>
<demo><mrk id="1"/>foo &amp; bar</demo>

XLIFF 1.2 翻译

提供的 XML 看起来很像 XLIFF 1.2,但它缺少名称空间。命名空间增加了复杂性,因此对于以下示例,我假设它是必需的(否则使用前面的文档片段示例)。

$xliff = <<<'XML'
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
    <body>
        <trans-unit id="NFDBB2FA9-tu4" xml:space="preserve">
            <source xml:lang="en">He</source>
            <target xml:lang="id">He</target>
        </trans-unit>
        <trans-unit id="NFDBB2FA9-tu5" xml:space="preserve">
            <source xml:lang="en">She</source>
            <target xml:lang="id">She</target>
        </trans-unit>
    </body>
</xliff>
XML;

// simulate user input
$_POST = [
  'id' => 'NFDBB2FA9-tu5',
  'text' => '<mrk id="1">Banana</mrk>'
]; 

// bootstrap DOM
$document = new DOMDocument();
$document->loadXML($xliff);
$xpath = new DOMXpath($document);
$xpath->registerNamespace('x', 'urn:oasis:names:tc:xliff:document:1.2');

// fetch a specific target by id
$expression = '//x:trans-unit[@id="'.$_POST['id'].'"]/x:target';
foreach($xpath->evaluate($expression) as $target) {
    $fragment = $document->createDocumentFragment();
    // wrap the fragment text to define the default namespace for elements
    $fragment->appendXML(
      '<target xmlns="urn:oasis:names:tc:xliff:document:1.2">'.
        $_POST['text'].'</target>'
    );
    // clear target node content
    $target->textContent = '';
    // append new content
    if ($fragment->firstChild->hasChildNodes()) {
        $target->append(...$fragment->firstChild->childNodes);
    }
}

echo $document->saveXML();  

输出:

<?xml version="1.0"?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
    <body>
        <trans-unit id="NFDBB2FA9-tu4" xml:space="preserve">
            <source xml:lang="en">He</source>
            <target xml:lang="id">He</target>
        </trans-unit>
        <trans-unit id="NFDBB2FA9-tu5" xml:space="preserve">
            <source xml:lang="en">She</source>
            <target xml:lang="id"><mrk id="1">Banana</mrk></target>
        </trans-unit>
    </body>
</xliff>
于 2021-03-03T13:58:43.373 回答