小于和大于DOMDocument XML .lsg中的符号

时间:2019-07-01 13:52:47

标签: php xml domdocument limesurvey

我正在尝试使用PHP脚本向lsg文件(由XML组成)中添加一些新元素。然后将lsg文件导入到limesurvey中。问题是我不能正确添加需要添加的字符,例如<和>。它们仅作为其实体引用(例如<和>)出现,在导入到石灰调查中时无法正常工作。如果我手动将实体引用更改为<和>

我尝试使用PHP DOMDocument来做到这一点。我的代码与此类似:

$dom = new DOMDocument();
$dom->load('template.lsg');

$subquestions = $dom->getElementById('subquestions');

$newRow = $dom->createElement('row');
$subquestions->appendChild($newRow);

$properties[] = array('name' => 'qid', 'value' => "![CDATA[1]]");

foreach ($properties as $prop) {
    $element = $dom->createElement($prop['name']);
    $text = $dom->createTextNode($prop['value']);
    $startTag = $dom->createEntityReference('lt');
    $endTag = $dom->createEntityReference('gt');
    $element->appendChild($startTag);
    $element->appendChild($text);
    $element->appendChild($endTag);
    $supplier->appendChild($element);
}

$response = $dom->saveXML();
$dom->save('test.lsg');

这一行的结果是这样的:

<row>
        <qid>&lt;![CDATA[7]]&lt;</qid>
</row>

看起来应该像这样:

<row>
    <qid><![CDATA[7]]></qid>
</row>

有什么建议吗?

1 个答案:

答案 0 :(得分:1)

CDATA节是一种特殊的文本节点。它们的编码/解码少得多,并且保留前导/后缀空格。因此,DOM解析器应该从以下两个示例节点读取相同的值:

<examples>
  <example>text<example>
  <example><![CDATA[text]]]></example>
</examples>

要创建CDATA节,请使用DOMDocument::createCDATASection()方法并将其附加到其他任何节点上。 DOMNode::appendChild()返回附加的节点,因此您可以嵌套调用:

$properties = [
   [ 'name' => 'qid', 'value' => "1"]
];

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

// appendChild() returns the node, so it can be nested
$row = $subquestions->appendChild(
  $document->createElement('row')
);
// append the properties as element tiwth CDATA sections
foreach ($properties as $property) {
    $element = $row->appendChild(
        $document->createElement($property['name'])
    );
    $element->appendChild(
        $document->createCDATASection($property['value'])
    );
}

$document->formatOutput = TRUE;
echo $document->saveXML();

输出:

<?xml version="1.0"?>
<subquestions>
  <row> 
    <qid><![CDATA[1]]></qid>
  </row> 
</subquestions>

大多数情况下,使用普通文本节点效果更好。

foreach ($properties as $property) {
    $element = $row->appendChild(
        $document->createElement($property['name'])
    );
    $element->appendChild(
        $document->createTextNode($property['value'])
    );
}

可以使用DOMNode::$textContent属性对此进行优化。

foreach ($properties as $property) {
    $row->appendChild(
        $document->createElement($property['name'])
    )->textContent = $property['value'];
}