2013-02-02 39 views
5

मैं क्लाइंट-साइड (जावास्क्रिप्ट) पर एक XML दस्तावेज में दुकान उपयोगकर्ता के इनपुट करने के लिए कोशिश कर रहा हूँ से पहले एक्सएमएल से अमान्य वर्ण निकाल रहा है, और दृढ़ता के लिए सर्वर से संचारित कि।() XmlSerializer के साथ यह serializing

एक उपयोगकर्ता, उदाहरण के लिए, उस पाठ को एक एसटीएक्स चरित्र (0x2) शामिल में चिपकाया। XMLSerializer एसटीएक्स चरित्र से बच नहीं पाया, और इसलिए, अच्छी तरह से गठित एक्सएमएल को क्रमबद्ध नहीं किया गया था। या शायद .attr() कॉल एसटीएक्स चरित्र से बच जाना चाहिए था, लेकिन किसी भी मामले में, अवैध एक्सएमएल का उत्पादन किया गया था।

मैं, की इन-ब्राउज़र XmlSerializer() हमेशा ठीक से नहीं बनाया गया है उत्पादन की खोज कर रहा हूँ (और यहां तक ​​कि ब्राउज़र के अपने DOMParser()

यह उदाहरण संतुष्ट नहीं करता पता चलता है कि एसटीएक्स चरित्र है ठीक से XmlSerializer() द्वारा इनकोडिंग नहीं:

> doc = $.parseXML('<?xml version="1.0" encoding="utf-8" ?>\n<elem></elem>'); 
    #document 
> $(doc).find("elem").attr("someattr", String.fromCharCode(0x2)); 
    [ <elem someattr=​"">​</elem>​ ] 
> serializedDoc = new XMLSerializer().serializeToString(doc); 
    "<?xml version="1.0" encoding="utf-8"?><elem someattr=""/></elem>" 
> $.parseXML(serializedDoc); 
    Error: Invalid XML: <?xml version="1.0" encoding="utf-8"?><elem someattr=""/></elem> 

मैं कैसे इन-ब्राउज़र (मनमाने ढंग से उपयोगकर्ता के इनपुट द्वारा निर्धारित पैरामीटर वाला) एक XML दस्तावेज निर्माण करना चाहिए ऐसी है कि वह हमेशा अच्छी तरह से गठित किया जाएगा (सब कुछ सही तरीके से छोड़े)? मैं IE8 या IE7 समर्थन करने के लिए की जरूरत नहीं है।

(और हाँ, मैं सर्वर पर एक्सएमएल को मान्य करते हैं, लेकिन ब्राउज़र सर्वर एक दस्तावेज है कि ठीक से नहीं बनाया हाथ है, सबसे अच्छा सर्वर कर सकते हैं जो कि गरीब के लिए उपयोगी नहीं है इसे अस्वीकार है, उपयोगकर्ता)

+0

मुझे यकीन नहीं है कि स्रोत स्ट्रिंग चरित्र-दर-चरित्र के माध्यम से जाने से कहीं अधिक आसान है, जो आवश्यकतानुसार इकाइयों का अनुवाद करता है। – Pointy

+0

मैं ऐसा करने के लिए खुद पर भरोसा नहीं करता हूं (मुझे अन्य संभावित मुद्दों की तलाश करने के लिए एक्सएमएल को पर्याप्त रूप से भी पता नहीं है) ... मेरे लिए ऐसा करने के लिए एक सामान्य/मानक जेएस लाइब्रेरी है ISFfeFORXML (inString)? – Seth

+0

इसके अलावा, क्या आप दुर्घटना से संभवतः डबल-एंटाइटलाइजिंग समाप्त नहीं करेंगे? उदाहरण के लिए, यदि भविष्य में ब्राउज़र XMLSerializer() + attr() में प्राधिकारिकता समाप्त हो जाती है, तो आप डबल-एस्केपिंग समाप्त कर देंगे? – Seth

उत्तर

10

यहाँ एक समारोह sanitizeStringForXML है() जो या तो काम, या एक व्युत्पन्न समारोह से पहले तार को साफ करने के removeInvalidCharacters (XmlNode) जो एक डोम पेड़ पारित किया जा सकता है और हो जाता है ताकि गुण और textNodes स्वच्छ होगा इस्तेमाल किया जा सकता वे स्टोर करने के लिए सुरक्षित हैं।

var stringWithSTX = "Bad" + String.fromCharCode(2) + "News"; 
var xmlNode = $("<myelem/>").attr("badattr", stringWithSTX); 

var serializer = new XMLSerializer(); 
var invalidXML = serializer.serializeToString(xmlNode); 

// Now cleanse it: 
removeInvalidCharacters(xmlNode); 
var validXML = serializer.serializeToString(xmlNode); 

मैं non-restricted characters section of this wikipedia article से पात्रों की सूची पर इस आधार पर है, लेकिन अनुपूरक विमानों 5-हेक्स अंकों यूनिकोड वर्ण की आवश्यकता होती है, और जावास्क्रिप्ट regex, इस के लिए एक वाक्य रचना शामिल नहीं है तो अब के लिए, मैं मीटर सिर्फ उन्हें बाहर अलग करना (आप बहुत ज्यादा लापता नहीं कर रहे हैं ...):

// WARNING: too painful to include supplementary planes, these characters (0x10000 and higher) 
// will be stripped by this function. See what you are missing (heiroglyphics, emoji, etc) at: 
// http://en.wikipedia.org/wiki/Plane_(Unicode)#Supplementary_Multilingual_Plane 
var NOT_SAFE_IN_XML_1_0 = /[^\x09\x0A\x0D\x20-\xFF\x85\xA0-\uD7FF\uE000-\uFDCF\uFDE0-\uFFFD]/gm; 
function sanitizeStringForXML(theString) { 
    "use strict"; 
    return theString.replace(NOT_SAFE_IN_XML_1_0, ''); 
} 

function removeInvalidCharacters(node) { 
    "use strict"; 

    if (node.attributes) { 
     for (var i = 0; i < node.attributes.length; i++) { 
      var attribute = node.attributes[i]; 
      if (attribute.nodeValue) { 
       attribute.nodeValue = sanitizeStringForXML(attribute.nodeValue); 
      } 
     } 
    } 
    if (node.childNodes) { 
     for (var i = 0; i < node.childNodes.length; i++) { 
      var childNode = node.childNodes[i]; 
      if (childNode.nodeType == 1 /* ELEMENT_NODE */) { 
       removeInvalidCharacters(childNode); 
      } else if (childNode.nodeType == 3 /* TEXT_NODE */) { 
       if (childNode.nodeValue) { 
        childNode.nodeValue = sanitizeStringForXML(childNode.nodeValue); 
       } 
      } 
     } 
    } 
} 

ध्यान दें कि यह केवल गुण और textNodes की nodeValues ​​से अमान्य वर्ण निकाल देता है। यह टैग नाम या विशेषता नाम, टिप्पणियां इत्यादि की जांच नहीं करता है

+0

सुधार की सराहना की है, अगर वहाँ गलतियों हैं, मैं – Seth

+0

:-(पता नहीं 5HR खोज के बाद मेरी समस्या का समाधान, धन्यवाद – MOB