【问题标题】:How to keep DOMDocument from saving < as &lt如何防止 DOMDocument 将 < 保存为 &lt
【发布时间】:2011-03-26 08:13:56
【问题描述】:

我正在使用 simpleXML 在我的一个 XML 文档中添加一个子节点...当我对我的 simpleXML 对象执行 print_r 时,&amp;lt; 在视图源中仍显示为&amp;lt; .但是,在我使用 DOMDocument 将此对象保存回 XML 后,&amp;lt; 被转换为 &amp;lt;&amp;gt; 被转换为 &amp;gt;

关于如何改变这种行为的任何想法?我试过添加dom-&gt;substituteEntities = false;,但这没有用。

    //Convert SimpleXML element to DOM and save
    $dom = new DOMDocument('1.0');
    $dom->preserveWhiteSpace = false;
    $dom->formatOutput = false;
    $dom->substituteEntities = false;
    $dom->loadXML($xml->asXML());
    $dom->save($filename);

这里是我使用 <:>

$new_hint = '<![CDATA[' . $value[0] . ']]>';               
$PrintQuestion->content->multichoice->feedback->hint->Passage->Paragraph->addChild('TextFragment', $new_hint);

问题是,我正在使用简单的 XML 来遍历 XML 文档中的某些节点,如果某个属性与给定的 ID 匹配,则使用 CDATA 添加一个特定的子节点。然后在所有处理之后,我使用 DOMDocument 将 XML 保存回文件,这是

这是我的整个课程文件的链接,因此您可以更好地了解我要完成的工作。具体参考底部的hint_insert()方法。

http://pastie.org/1079562

【问题讨论】:

  • &amp;lt; 在 XML 元素中根本不是合法字符(除非您在 CDATA 部分中)。你想完成什么?
  • 我正在尝试完成添加 CDATA 标记...检查原始帖子以获取更新的代码
  • 感谢您的反对!当节点中有“”时,CDATA 标记在 xml 中是必需的(除非您转义)!与 XHTML 相同...
  • 嗯,我没给你投反对票
  • 这个问题与stackoverflow.com/questions/3418796/…有何不同?

标签: php xml simplexml domdocument


【解决方案1】:

问题在于您可能会将其添加为字符串,而不是元素。

所以,而不是:

$simple->addChild('foo', '<something/>');

将被视为文本:

$child = $simple->addChild('foo');
$child->addChild('something');

您不能在 XML 文档的正文中包含文字 &lt;,除非它是标签的开头。

编辑:根据你在 cmets 中的描述,我想你是在追求:

DomDocument::createCDatatSection()

$child = $dom->createCDataSection('your < cdata > body ');
$dom->appendChild($child);

Edit2:阅读您的编辑后,我只能说一件事:

You're doing it wrong... 您不能将元素添加为另一个元素的字符串值。对不起,你不能。这就是它逃避事物的原因,因为 DOM 和 SimpleXML 可以确保您始终创建有效的 XML。您需要将元素创建为对象...因此,如果要创建 CDATA 子项,则必须执行以下操作:

$child = $PrintQuestion.....->addChild('TextFragment');
$domNode = dom_import_simplexml($child);
$cdata = $domNode->ownerDocument->createCDataSection($value[0]); 
$domNode->appendChild($cdata);

这就是它应该有的一切......

【讨论】:

  • CDATA 标签的打开和关闭给我带来了问题...请参考原帖。
  • 这也是正确答案,只是当时没看懂。不过还是投了赞成票,谢谢。
【解决方案2】:

SimpleXML 和 php5 的 DOM module 使用相同的文档内部表示(由 libxml 促进)。您可以在两个 api 之间切换,而无需通过 simplexml_import_dom() 和 dom_import_simplexml() 重新解析文档。
IE。如果您真的想/必须在找到元素后使用 SimpleXML api 执行迭代,您可以在 same 文档中切换到 DOM api 和 create the CData section

<?php
$doc = new SimpleXMLElement('<a>
  <b id="id1">a</b>
  <b id="id2">b</b>
  <b id="id3">c</b>
</a>');


foreach( $doc->xpath('b[@id="id2"]') as $b ) {
  $b = dom_import_simplexml($b);
  $cdata = $b->ownerDocument->createCDataSection('0<>1');
  $b->appendChild($cdata);
  unset($b);
}

echo $doc->asxml();

打印

<?xml version="1.0"?>
<a>
  <b id="id1">a</b>
  <b id="id2">b<![CDATA[0<>1]]></b>
  <b id="id3">c</b>
</a>

【讨论】:

  • 谢谢。这是我需要的信息。我没有意识到我可以互换使用两者。
  • 设置 $b = dom_import_simplexml($b) 会扰乱迭代吗?
  • "设置 $b= ... 会扰乱迭代吗?" - 显然不是 ;-) 但如果你愿意,可以使用另一个变量。我只是希望变量尽可能少(在合理范围内,例如 $cdata 也可以省略),并且由于 $b 没有其他用途,我重复使用它。
猜你喜欢
  • 2020-03-27
  • 2021-10-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-21
  • 2011-11-12
  • 1970-01-01
相关资源
最近更新 更多