2010-12-09 14 views
8

मैं स्कैला और एक्सएमएल के साथ प्रयोग कर रहा हूं और मुझे XML.load (या loadString) के साथ बनाए गए XML टैग के बीच व्यवहार में एक अजीब अंतर मिला और इसे शाब्दिक के रूप में लिखना पड़ा।स्कैला XML.loadString बनाम शाब्दिक अभिव्यक्ति

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

और यहाँ, उत्पादन:

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 

प्रकार एक ही हैं यहाँ कोड है। लेकिन समानता नहीं है। गुणों का क्रम बदलता है। यह मूल के समान कभी नहीं होता है। कड़वाहट के गुण वर्णानुक्रम से क्रमबद्ध हैं (केवल खतरे?)।

यह समस्या नहीं होगी यदि दोनों समाधानों को बदलने की कोशिश करते समय दोनों समाधान अलग-अलग व्यवहार नहीं करते हैं। मैंने How to change attribute on Scala XML Element पर डैनियल सी सोब्राल से कुछ अंतर्निहित कोड उठाया और "href" विशेषता के पहले स्लैश को हटाने के लिए अपना खुद का नियम लिखा। RuleTransformer in_xml के साथ अच्छी तरह से काम करता है, लेकिन इसका कोई प्रभाव नहीं है!

दुर्भाग्यवश, मेरे अधिकांश कार्यक्रमों को XML.load (...) के माध्यम से XML को पढ़ना है। तो, मैं अटक गया हूँ। क्या कोई इस विषय के बारे में जानता है?

सादर,

हेनरी

+1

यह निश्चित रूप से एक बग है। ऐसा नहीं है कि मदद करता है ... –

+0

स्कैला एक्सएमएल अक्षरों को विशेषता आदेश के साथ समस्याएं ज्ञात हैं। आप http://lampsvn.epfl.ch/trac/scala/ticket/2735 को अप-वोट कर सकते हैं। (मुझे नहीं पता कि वे वास्तव में वोटों पर ध्यान देते हैं, लेकिन यह चोट नहीं पहुंचा सकता है।) – Steve

+0

वे वोटों पर ध्यान नहीं देते हैं, हालांकि वे गतिविधि पर ध्यान देते हैं (लोग सदस्यता लेते हैं, टिप्पणी करते हैं आदि)। फिर भी, यह चोट नहीं पहुंचाता है। मैं, व्यक्तिगत रूप से, किसी भी बग की सदस्यता लेता हूं जिसमें मुझे रूचि है, और जो भी मुझे लगता है वह विशेष रूप से महत्वपूर्ण है। –

उत्तर

0

कुछ आगे की जांच: हो सकता है, मेरी प्रारंभिक समानता परीक्षण नहीं उचित है:

in_xml == from_str 

और अगर मैं परीक्षण:

in_xml.equals(in_xml) 

मुझे भी झूठा लगता है। हो सकता है, मैं एक और परीक्षण विधि का उपयोग करना चाहिए (मेल खाती है की तरह है, लेकिन मैं बाहर नहीं मिला जो एक विधेय मैं दूसरा पैरामीटर के रूप में इस्तेमाल करना चाहिए ...)

कहा, अगर मैं परीक्षण आरईपीएल में निम्नलिखित

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

मैं सच मिलता है, यहां तक ​​कि बराबरी विधि बुला के बिना ...

मेरी प्रारंभिक उदाहरण पर वापस मैं रीराइट नियम

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

यह सहायक वर्गों/तरीकों का उपयोग करता परिभाषित How to change attribute on Scala XML Element पर डैनियल सी सोब्राल द्वारा परिभाषित किया गया। अगर मैं लागू होते हैं:

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

मैं in_xml साथ अपेक्षित परिणाम मिलता है, लेकिन from_str साथ कोई संशोधन ...

1

मैं क्या देख सकते हैं से, in_xml और from_str नहीं के बराबर होती है, क्योंकि विशेषताओं के आदेश हैं विभिन्न। यह दुर्भाग्यपूर्ण है और जिस तरह से एक्सएमएल संकलक द्वारा बनाया गया है।

scala> in_xml.copy(attributes=from_str.attributes) == from_str 
res32: Boolean = true 
कहा, मैं स्पष्ट क्यों कि कारण होगा नहीं कर रहा हूँ कि साथ

:

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

आप देखते हैं कि अगर आप विशेषताओं की जगह तुलना काम करेंगे देख सकते हैं: यह गुण अलग होने की कारण बनता है कोड में एक अलग व्यवहार जो href विशेषता को प्रतिस्थापित करता है। असल में मुझे संदेह है कि विशेषता मैपिंग के तरीके के साथ कुछ गलत है। उदाहरण के लिए, अगर मैं बदलने के साथ in_str:

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

यह ठीक काम करता है। क्या यह हो सकता है कि डैनियल से विशेषता कोड केवल तभी काम करता है जब विशेषता MetaData की मुख्य स्थिति में है?


साइड नोट: जब तक in_xml है null, equals और == समान मान जाएगा। == संस्करण यह जांच करेगा कि equals पर कॉल करने से पहले पहला ऑपरेंड शून्य है या नहीं।

संबंधित मुद्दे