如何正确比较 scala.xml 节点?

弗拉迪斯拉夫·瓦尔斯拉万

我试图在scala中比较两个XML,但是scala所做的比较没有意义。如何正确地做到这一点?

假设我们有两个 xml:

import scala.xml.Elem

val xml1: Elem = <A><B>   SomeText   </B></A>

val xml2: Elem = <A>
  <B>   SomeText   </B>
</A>

然后我比较它,我得到奇怪的结果:

xml1.diff(xml2)
// res0: scala.xml.NodeSeq = NodeSeq(<A><B>   SomeText   </B></A>)

xml1.mkString eq xml2.mkString
// res1: Boolean = false

xml1.descendant == xml2.descendant
// res2: Boolean = false

xml1 == xml2
// res5: Boolean = false

xml1.equals(xml2)
// res6: Boolean = false

调用trimxmls 将不起作用,因为这会破坏 XMLs 本身:

scala.xml.Utility.trim(xml1)
// res3: scala.xml.Node = <A><B>SomeText</B></A>

scala.xml.Utility.trimProper(xml1)
// res4: Seq[scala.xml.Node] = <A><B>SomeText</B></A>

在 Scala 中比较 XML 的正确方法是什么(没有任何额外的库)?有没有?为什么 Scala 会进行这种奇怪的比较?

斯卡拉版本2.11.11

更新

令我困惑的是 - 从我的角度来看,这些是完全相同的 XML - 都具有根节点<A>,节点<A>包含节点<B>和节点<B>包含SomeText

例如,如果它是 JSON,则相同。

{ "A" : { "B" : " SomeText " } }

{ 
   "A" : {
       "B" : "   SomeText   " 
   } 
}

从我的角度来看,XML 的编写方式无关紧要——多行或单行。它仍然是相同的 XML - 相同的结构和相同的内容。在这一点上我错了吗?

佐兰·杰雷米克

我不认为将这两个 xml 作为字符串进行比较会起作用,因为第二个 xml 有换行符,并且作为字符串,它将解析为 \n SomeText \n ,这就是为什么将其作为字符串进行比较时总是出错的原因.

当您使用修剪时,这些换行符和空格将被删除,因此如果您不想被忽略,您可能宁愿比较每个单独的子元素,例如

(xml1 \ "B").text == (xml2 \ "B").text

并定义您自己的平等标准。

另一方面,从两个 xml 直接比较节点 A 也不起作用,因为节点 B 前面的换行符和空格被视为 xml2 中节点 A 的子元素。因此,来自 xml2 的节点 A 将有 3 个子节点(文本节点“\n”、节点 B 和文本节点“\n”),而来自 xml1 的节点 A 将只有 1 个子节点(节点 B)。那些节点 A 的比较总是错误的。

您可以查看这篇文章oracle.com/technical-resources/articles/wang-whitespace.html以查找有关元素前后空格的更多信息。这是java示例,但几乎相同的想法。这也可能有助于理解问题:xmlplease.com/xml/xmlspace/#s3您会从中了解到空格和换行符被视为父节点的子元素,这就是直接比较这两个元素不起作用的原因。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章