小于和大于符号在 DOMDocument XML .lsg
Less than and greater than sign in DOMDocument XML .lsg
我正在尝试使用 PHP 脚本向 lsg 文件(由 XML 组成)添加一些新元素。然后将 lsg 文件导入到 limesurvey 中。问题是我无法正确添加我需要添加的字符,例如 < 和 >。它们仅显示为它们的实体引用(例如 < 和 >),在导入到 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><![CDATA[7]]<</qid>
</row>
虽然它应该看起来像这样:
<row>
<qid><![CDATA[7]]></qid>
</row>
有什么建议吗?
CDATA 部分是一种特殊的文本节点。他们 encode/decode 少了很多,他们保留了 leading/trailing 空格。因此 DOM 解析器应该从以下两个示例节点读取相同的值:
<examples>
<example>text<example>
<example><![CDATA[text]]]></example>
</examples>
要创建 CDATA 部分,请使用 DOMDocument::createCDATASection()
方法并像任何其他节点一样附加它。 DOMNode::appendChild()
returns 附加节点,因此您可以嵌套调用:
$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'];
}
我正在尝试使用 PHP 脚本向 lsg 文件(由 XML 组成)添加一些新元素。然后将 lsg 文件导入到 limesurvey 中。问题是我无法正确添加我需要添加的字符,例如 < 和 >。它们仅显示为它们的实体引用(例如 < 和 >),在导入到 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><![CDATA[7]]<</qid>
</row>
虽然它应该看起来像这样:
<row>
<qid><![CDATA[7]]></qid>
</row>
有什么建议吗?
CDATA 部分是一种特殊的文本节点。他们 encode/decode 少了很多,他们保留了 leading/trailing 空格。因此 DOM 解析器应该从以下两个示例节点读取相同的值:
<examples>
<example>text<example>
<example><![CDATA[text]]]></example>
</examples>
要创建 CDATA 部分,请使用 DOMDocument::createCDATASection()
方法并像任何其他节点一样附加它。 DOMNode::appendChild()
returns 附加节点,因此您可以嵌套调用:
$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'];
}