2012-10-09 14 views
23

है जब मैं निम्नलिखित न्यूनतम जावास्क्रिप्ट टुकड़ा है:क्रोम 22 outputs अमान्य XML गुण एक XLink नाम स्थान

var xml = '<El a:title="T" a:href="H" xmlns:a="http://www.w3.org/1999/xlink" />'; 
var dom = new DOMParser().parseFromString(xml, 'text/xml'); 
xml = new XMLSerializer().serializeToString(dom); 

जब मैं सबसे ब्राउज़रों में कोड निष्पादित (सिर्फ अपने ब्राउज़र का JavaScript कंसोल में पेस्ट), पार्स-टू-सीरियलाइज्ड एक्सएमएल मूल के बराबर है। क्रोम 8 पर उदाहरण के लिए मैं:

<El xmlns:a="http://www.w3.org/1999/xlink" a:title="T" a:href="H"/> 
हालांकि

क्रोम 22 पर एक ही कोड टुकड़ा करने के लिए XML परिवर्तन:

<El xmlns:a="http://www.w3.org/1999/xlink" xlink:title="T" xlink:href="H"/> 

ध्यान दें कि नामस्थान उपसर्ग xlink शीर्षक और href गुण द्वारा नहीं किया जाता है कहीं भी परिभाषित किया गया है, इसलिए एक्सएमएल अब अमान्य है। जैसा कि आप शायद कल्पना कर सकते हैं कि यह कोड के लिए सभी प्रकार की समस्याओं का कारण बनता है जो बाद में एक्सएमएल का उपयोग करने की कोशिश करता है।

क्या यह XMLSerializer में एक बग है या क्या मुझे कुछ जटिलताएं याद आ रही हैं कि डीओएम को क्रमबद्ध कैसे किया जाना चाहिए?

क्या किसी को भी एक वर्कअराउंड मिल गया है जिसे मैं कोड में डाल सकता हूं, एक्सएमएल को एक्सलिंक नामस्थान के उपसर्ग के रूप में xlink का उपयोग करने के लिए स्पष्ट वरीयता का मिलान करने के विरोध में?

अद्यतन

मैं कुछ अतिरिक्त परीक्षण किया था और समस्या तथ्य यह है कि XmlSerializer XLink नाम स्थान को पहचानता है और इसके लिए एक xlink उपसर्ग outputting, ठीक से कि उपसर्ग पंजीकरण किए बिना पर जोर की वजह से हो रहा है।

तो यह टुकड़ा काम ठीक:

var xml = '<El a:title="T" a:href="H" xmlns:a="any-other-namespace-uri" />'; 
var dom = new DOMParser().parseFromString(xml, 'text/xml'); 
xml = new XMLSerializer().serializeToString(dom); 

तो यहाँ मैं कुछ कम प्रसिद्ध करने के लिए नाम स्थान यूआरएल बदल गया है और उत्पादन अब मान्य है:

निम्नलिखित टुकड़ा भी ठीक काम करता है :

var xml = '<El a:title="T" a:href="H" xmlns:a="http://www.w3.org/2000/xlink" />'; 
var dom = new DOMParser().parseFromString(xml, 'text/xml'); 
xml = new XMLSerializer().serializeToString(dom); 

तो इस मामले में हम XLink नामस्थान के लिए "अपेक्षित" उपसर्ग का उपयोग करते हैं और यह तो समस्याओं के बिना serializes:

<El xmlns:a="http://www.w3.org/2000/xlink" a:title="T" a:href="H"/> 
+4

मुझे पूरा यकीन नहीं है कि उत्तर क्या है, लेकिन यह समस्या संबंधित हो सकती है: http://stackoverflow.com/questions/8979267/xmlserializer-strips-xlink-from-xlinkhtml-svg-image-tag – Barbarrosa

+0

धन्यवाद पॉइंटर Barbarrosa के लिए। मैंने क्रोम के एसवीजी/एक्सलिंक हैंडलिंग के बारे में रिपोर्ट देखी थी। लेकिन मुझे वास्तव में डर है कि इसके लिए "फिक्स" हो सकता है जिसके कारण मुझे समस्या आ रही है। आपके लिंक के साथ मैं वास्तव में अपमानजनक कोड के करीब एक कदम प्राप्त कर सकता हूं, इसलिए धन्यवाद! –

उत्तर

7

मैं अभी भी काफी कुछ वहाँ Chrome की XMLSerializer में एक बग है कि कर रहा हूँ, सबसे अधिक संभावना है, जबकि SVG handling of XLink attributes that Barbarrosa pointed to को संबोधित की शुरुआत की। लेकिन bug report पर प्रतिक्रिया की कमी के कारण मैंने इसके लिए बनाया, हमें आगे बढ़ना पड़ा और समस्या के आसपास काम करना पड़ा।

हम documentElement पर इस कार्यप्रणाली को कॉल करके समस्या को हल करने:

function EnsureXLinkNamespaceOnElement(element) 
{ 
    if (element.nodeType == 1) 
    { 
    var usesXLinkNamespaceUri = false; 
    var hasXLinkNamespacePrefixDefined = false; 
    for (var i = 0; i < element.attributes.length; i++) 
    { 
     var attribute = element.attributes[i]; 
     if (attribute.specified) 
     { 
     if (attribute.name.indexOf("xmlns:xlink") == 0) 
     { 
      hasXLinkNamespacePrefixDefined = true; 
     } 
     else if (attribute.namespaceURI == "http://www.w3.org/1999/xlink") 
     { 
      usesXLinkNamespaceUri = true; 
     } 
     } 
    } 
    if (usesXLinkNamespaceUri && !hasXLinkNamespacePrefixDefined) 
    { 
     element.setAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink'); 
    } 

    for (i = 0; i < element.childNodes.length; i++) 
    { 
     EnsureXLinkNamespaceOnElement(element.childNodes[i]); 
    } 
    } 
} 

समारोह बस सुनिश्चित करता है कि xmlns:xlink विशेषता किसी भी तत्व है कि XLink नाम स्थान में जिम्मेदार ठहराया है पर घोषित किया जाता है। चूंकि फ़ंक्शन पेड़ को पार करता है और इस प्रकार काफी समय लेने वाला हो सकता है, मैं केवल इसे क्रोम संस्करण 22 और उच्चतर के लिए आमंत्रित करता हूं।

ध्यान दें कि ज्यादातर मामलों में आप दस्तावेज़ तत्व पर xmlns:xlink नामस्थान जोड़कर भी दूर हो सकते हैं, क्योंकि यह वहां से विरासत में मिलेगा।लेकिन हमारे मामले में कुछ अन्य कोड था जो एक नियमित अभिव्यक्ति का उपयोग करके दस्तावेज़ तत्व को स्ट्रिप्स करता था, इसलिए हमने इसे सुरक्षित खेलने का फैसला किया और बस हर जगह विशेषता को जोड़ दिया।

अद्यतन (20,130,324):

bug तय किया गया था और क्रोम कैनरी 26. में सत्यापित मैं भी संस्करण 25.0.1364.172 m पर इसे अपने आप को सत्यापित करने के लिए सक्षम है।

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