Scala XML.loadString vs文字表达式

Hen*_*uer 8 xml string comparison scala transformation

我一直在尝试使用Scala和XML,我发现使用XML.load(或loadString)创建的XML标记与将其写为文字的行为之间存在奇怪的差异.这是代码:

import scala.xml._
// creating a classical link HTML tag
val in_xml = <link type="text/css" href="/css/main.css" rel="stylesheet" xmlns="http://www.w3.org/1999/xhtml"></link>
// The same as a String
val in_str = """<link type="text/css" href="/css/main.css" rel="stylesheet" xmlns="http://www.w3.org/1999/xhtml"></link>"""
// Convert the String into XML
val from_str = XML.loadString(in_str)

println("in_xml  : " + in_xml)
println("from_str: "+ from_str)
println("val_xml == from_str: "+ (in_xml == from_str))
println("in_xml.getClass() == from_str.getClass(): " +
  (in_xml.getClass() == from_str.getClass()))
Run Code Online (Sandbox Code Playgroud)

在这里,输出:

in_xml  : <link href="/css/main.css" rel="stylesheet" type="text/css" xmlns="http://www.w3.org/1999/xhtml"></link>
from_str: <link rel="stylesheet" href="/css/main.css" type="text/css" xmlns="http://www.w3.org/1999/xhtml"></link>
val_xml == from_str: false
in_xml.getClass() == from_str.getClass(): true
Run Code Online (Sandbox Code Playgroud)

类型是相同的.但是没有平等.属性的顺序会发生变化.它永远不会与原来的相同.邮件的属性按字母顺序排序(只有危险?).

如果我尝试转换它们时两个解决方案的行为都不同,那么这不会成为问题.我从Daniel C. Sobral那里获取了一些有趣的代码,如何更改Scala XML Element的属性并编写我自己的规则以删除"href"属性的第一个斜杠.RuleTransformer适用于in_xml,但对from_str没有影响!

不幸的是,我的大部分程序都必须通过XML.load(...)读取XML.所以,我被困住了.有人知道这个话题吗?

最好的祝福,

亨利

小智 0

一些进一步的测试:也许,我最初的相等测试不合适:

in_xml == from_str
Run Code Online (Sandbox Code Playgroud)

如果我测试:

in_xml.equals(in_xml)
Run Code Online (Sandbox Code Playgroud)

我也得到假的。也许,我应该使用另一种测试方法(例如对应,但我没有找到应该使用什么谓词作为第二个参数......)

也就是说,如果我在 REPL 中测试以下内容

<body id="1234"></body> == XML.loadString("<body id=\"1234\"></body>")
Run Code Online (Sandbox Code Playgroud)

我明白了,即使没有调用 equals 方法......

回到我最初的例子:我定义了一个重写规则

def unSlash(s: String) = if (s.head == '/') s.tail else s
val changeCSS = new RewriteRule {
    override def transform(n: Node): NodeSeq = n match {
        case e: Elem if (n \ "@rel").text == "stylesheet" =>
            e.copy(attributes = mapMetaData(e.attributes) {
                case g @ GenAttr(_, key, Text(v), _) if key == "href" =>
                    g.copy(value = Text(unSlash(v)))
                case other => other
            })
        case n => n
    }
}
Run Code Online (Sandbox Code Playgroud)

它使用 Daniel C. Sobral 在如何更改 Scala XML 元素上的属性中定义的帮助器类/方法。如果我申请:

new RuleTransformer(changeCSS).transform(in_xml)
new RuleTransformer(removeComments).transform(from_str)
Run Code Online (Sandbox Code Playgroud)

我使用 in_xml 得到了预期的结果,但没有使用 from_str 进行修改...