【问题标题】:In PHP, how to saveXML with the attributes sorted?在 PHP 中,如何使用已排序的属性保存 XML?
【发布时间】:2021-07-09 14:35:45
【问题描述】:

如果我有一个 DOMDocument 并且我想将它解析为一个字符串,我如何确保属性将按某种确定性/规范化顺序排序(根据属性名称按字典顺序排序会很好)?

例如,我怎样才能打印equal 而不是notequal

 $dom = new DOMDocument();
 $dom->loadXML('<tag a="a" b="b"/>');
 
 $dom2 = new DOMDocument();
 $dom2->loadXML('<tag b="b" a="a"/>');

 echo $dom->saveXML() === $dom2->saveXML() ? "equal" : "notequal";

根据documentationsaveXML 唯一支持的选项是LIBXML_NOEMPTYTAG

【问题讨论】:

  • 除了你的例子,请问你为什么要这样做?通常属性的顺序是无关紧要的。
  • @KIKO Software 在我的情况下,它背后的原因非常愚蠢(试图以最少的更改来修复遗留代码)但总的来说,我认为问题并不那么愚蠢,正如您在this answer Java 中的类似问题
  • 我没有问“为什么”,因为我认为这个问题很愚蠢,我问它是否有替代方法。人们经常只问他们想做什么,而不解释“为什么”。例如,如果您问我们如何以最少的更改修复遗留代码,您可能会对答案感到惊讶。当然,您需要提供代码、您想要更改的内容以及您的尝试。如果您的尝试是正确的方法,人们会帮助您改进它,但可能有更好的方法您甚至没有想到。
  • 在当前问题的情况下,您在saveXMS()的选项中寻找答案,而我认为在保存它们之前对dom节点进行排序更有意义。

标签: php xml domdocument


【解决方案1】:

DOMNode::C14N() 将节点规范化为字符串。

$expected = new DOMDocument();
$expected->loadXML('<tag a="a" b="b"/>');

$actual = new DOMDocument();
$actual->loadXML('<tag b="b" a="a"/>');

echo $expected->C14N() === $actual->C14N() ? "equal" : "notequal";

输出:

equal

如果您正在编写单元测试 - PHPUnit 有特定的 XML 断言。

  • assertXmlFileEqualsXmlFile()
  • assertXmlStringEqualsXmlFile()
  • assertXmlStringEqualsXmlString()

【讨论】:

  • -&gt;C14N() 向我返回 false,即使我将它传递给了有效的 xml。如何发现错误(获取堆栈跟踪或其他内容)而不是仅获取 false 值?
  • 实际上我认为我的问题是我们有相对 URI:github.com/robrichards/xmlseclibs/issues/… 太糟糕了,除非我先修复我的 URI,否则我不能真正使用 C14N
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-01
  • 1970-01-01
  • 2014-12-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多