2010-12-09 12 views
8

Scala ve XML ile denemeler yapıyorum ve XML.load (veya loadString) ile oluşturulmuş bir XML etiketi ile bir literal olarak yazarken davranışlarda garip bir fark buldum. BuradaScala XML.loadString vs literal ifade

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())) 

Ve çıkış:

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 

türleri aynıdır İşte kodudur. Ama eşitlik yok. Özelliklerin sırası değişir. Asla orijinal olanla aynı değildir. Litteral'ın nitelikleri alfabetik olarak sıralanmıştır (sadece tehlike?).

Her iki çözüm de, dönüştürmeyi denediğimde farklı davranmazsa bu sorun olmaz. Daniel C. Sobral'dan How to change attribute on Scala XML Element numaralı telefondan bazı gizli kodları aldım ve "href" özniteliğinin ilk çizgisini kaldırmak için kendi kuralımı yazdım. RuleTransformer in_xml ile iyi çalışır, ancak from_str!

Ne yazık ki, çoğu programım XML.load (...) aracılığıyla XML'i okumak zorunda. Yani sıkıştım. Birisi bu konu hakkında biliyor mu?

Saygılarımızla,

Henri

+1

Bu kesinlikle bir hatadır. Bu yardımcı olmuyor ... –

+0

Scala XML editörleri, özellik sırasına göre bilinen sorunlar yaşıyor. Http://lampsvn.epfl.ch/trac/scala/ticket/2735 adresine oy verebilirsiniz. (Oy vermelerine gerçekten dikkat etseler bile bilmiyorum, ama canını acıtmaz.) – Steve

+0

Oylamaya dikkat etmeseler de, aktiviteye dikkat etmelerine rağmen (abone, yorum yapma, vb.). Yine de, incitmez. Ben şahsen, ilgilendiğim herhangi bir hataya abone oluyorum ve özellikle önemli olduğunu düşündüğüm herhangi bir şeyi kabul ediyorum. –

cevap

0

Bazı ileri testler:

in_xml == from_str 

ve ben sınamak eğer: Belki, benim ilk eşitlik testi uygun değildir

in_xml.equals(in_xml) 

Ben de yanlış olurum. Belki, başka test yöntemi kullanmalısınız (karşılık gelir gibi ama dışarı bulamadık ne ikinci parametre olarak kullanması gereken bir yüklem ...) Ben sınamak eğer repl aşağıdaki dedi

<body id="1234"></body> == XML.loadString("<body id=\"1234\"></body>") 

hatta eşittir yöntemini çağırarak olmadan gerçek olsun ...

Geri benim ilk örneğe: Ben bir yeniden yazma kuralı Bu yardımcı sınıflar/yöntemleri kullanır

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 
    } 
} 

tanımlanmış Daniel C. Sobral tarafından How to change attribute on Scala XML Element numaralı telefondan tanımlanmıştır. Ben geçerliyse:

new RuleTransformer(changeCSS).transform(in_xml) 
new RuleTransformer(removeComments).transform(from_str) 

Ben in_xml ile beklenen sonuç almak, ama from_str ile hiçbir değişiklik ...

1
Görebildiğim kadarıyla

, in_xml ve from_str niteliklerin sırası olduğu için değil eşit olan farklı. Bu talihsiz ve XML'in derleyici tarafından yaratılmasından dolayı.O neden neden açık değilim, dedi dikkate

scala> in_xml.copy(attributes=from_str.attributes) == from_str 
res32: Boolean = true 

: Eğer özelliklerini değiştirmek eğer karşılaştırma çalışacak görüyoruz

scala> in_xml.attributes == from_str.attributes 
res30: Boolean = false 

görebilirsiniz: Bu farklı olmak özelliklerini neden olur href özniteliğinin yerini alan kodda farklı bir davranış. Aslında, özellik haritalama çalışmalarında bir şeylerin yanlış olduğunu sanıyorum.

val in_str = """<link type="text/css" rel="stylesheet" href="/css/main.css" 
xmlns="http://www.w3.org/1999/xhtml"></link>""" 

Düzgün çalışır: Mesela ben in_str ile değiştirirseniz. Daniel'in öznitelik kodu, yalnızca öznitelik MetaData'un baş konumundaysa çalışır mı?


Yan not: in_xml olmadıkça null, equals ve == aynı değeri döndürecektir. == sürümü, ilk işlenenin equals numaralı telefonu aramadan önce boş olup olmadığını denetler.