2013-02-02 18 views
5

Kullanıcı girdisini istemci tarafında (javascript) bir XML belgesinde depolamaya çalışıyorum ve bunu kalıcılık için sunucuya iletiyorum. Örneğin, bir kullanıcı bir STX karakteri (0x2) içeren bir metne yapıştırılmıştır. XMLSerializer, STX karakterinden kaçmadı ve bu nedenle, iyi biçimlendirilmiş XML'e serileştirilmedi. Ya da belki de .attr() çağrısı STX karakterinden kaçmış olmalı, ancak her iki durumda da geçersiz XML üretildi.XMLSerializer() ile serileştirilmeden önce geçersiz karakterleri XML'den kaldırma()

Ben, tarayıcı XMLSerializer() her zaman iyi biçimli değildir çıktısını buluyorum (ve hatta tarayıcının kendi DOMParser()

Bu örnek tatmin etmiyor STX karakteri olduğunu gösteriyor düzgün XmlSerializer'ı() tarafından kodlanmamış:

> 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> 
her zaman iyi oluşacak nasıl tarayıcı içi (keyfi kullanıcı girişi ile belirlenir parametreleri içeren) bir XML belgesi oluşturmalıdır şekilde

(herşey düzgün kaçtı)? IE8 veya IE7'yi desteklemem gerekmez.(Ve evet, ben sunucu tarafında XML doğrulamak, ancak tarayıcı sunucu iyi biçimlendirilmemiş bir belge el varsa, sunucunun yapabileceği en iyisi, bunu reddetmek, bu fakir için yararlı değil kullanıcı) İşte

+0

Gerekirse varlıklara karakter çevirerek, karakter dizgisi karakterinden daha kolay bir şey olmadığından emin değilim. – Pointy

+0

Bunu yapmak için kendime güvenmeyeceğim (XML'in DİĞER olası sorunları araştırmaya yetecek kadar iyi bile bilmiyorum) ... makeSafeForXML (inString) için bunu yapmak için ortak bir/standart JS kitaplığı var mı? – Seth

+0

Ayrıca, muhtemelen kazara iki katına çıkarılmayacak mısın? Örneğin, gelecekteki bir tarayıcıda XMLSerializer() + attr() öğesi yetkilendirmeyi bitirirse, siz çıkış yapamazsınız? – Seth

cevap

10

bir işlev sanitizeStringForXML var() ya atama veya türev fonksiyonu önce removeInvalidCharacters bir DOM ağacı geçirilebilir ve otomatik böylece özelliklerini ve textNodes sterilize edecek (XMLNode) dizeleri temizlemek için kullanılabilecek saklamak için güvenli.

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

ben non-restricted characters section of this wikipedia article karakterlerin listesi dayandırdı, ancak ek düzlemler 5-altıgen haneli unicode karakterler gerektiren ve şimdi, ben bu yüzden JavaScript regex, bunun için bir sözdizimi içermez Ben sadece (eğer ... çok fazla eksik değildir) onları sıyırma: Bu sadece özellik ve textNodes ait nodeValues ​​geçersiz karakterleri kaldırır o

// 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); 
       } 
      } 
     } 
    } 
} 

Not. Etiket adlarını veya nitelik adlarını, yorumları vb. Kontrol etmiyor.

+0

hatalar varsa, karakter listesi için takdirleri takdir, bilmiyorum :-( – Seth

+0

5hr arama sonra benim sorunumu çözmek, teşekkürler – MOB