在使用 XMLSerializer() 序列化 XML 之前从 XML 中删除无效字符
Removing invalid characters from XML before serializing it with XMLSerializer()
我正在尝试将用户输入存储在客户端(javascript)的XML文档中,并将其传输到服务器以进行持久性。
例如,一个用户粘贴的文本包含 STX 字符 (0x2)。XMLSerializer 未转义 STX 字符,因此未序列化为格式正确的 XML。或者,也许 .attr() 调用应该转义了 STX 字符,但在这两种情况下,都会生成无效的 XML。
我发现浏览器内XMLSerializer()的输出并不总是格式良好的(甚至不满足浏览器自己的DOMParser()
此示例显示 XMLSerializer() 未正确编码 STX 字符:
> 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。
(是的,我确实在服务器端验证了XML,但是如果浏览器向服务器提供了格式不正确的文档,服务器所能做的最好的事情就是拒绝它,这对可怜的用户没有多大帮助)
这是一个函数sanitizeStringForXML(),它可以用来在赋值前清理字符串,或者一个派生函数removeInvalidCharacters(xmlNode),它可以传递一个DOM树,并将自动清理属性和textNode,以便它们安全存储。
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);
我基于这篇维基百科文章的非限制字符部分中的字符列表,但补充平面需要 5 个十六进制数字的 unicode 字符,而 Javascript 正则表达式不包括语法,所以现在,我只是将它们删除(你没有错过太多......
// 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);
}
}
}
}
}
请注意,这只会从属性和文本节点的节点值中删除无效字符。它不检查标签名称或属性名称、注释等。
检查https://gist.github.com/john-doherty/b9195065884cdbfd2017a4756e6409cc,
非常有用的要点,示例用法:
const resultXml = removeXMLInvalidChars(INPUT_XML_STRING, true);
- 使用AJAX传递的数据编辑XML文件-正在删除XML数据
- 如何使用Extendscript scriptui插入、更新、删除XML元素的值
- 如何从加载到javascript中的导出XML数据中删除不需要的空格
- 从谷歌地图xml中删除标记
- 需要有关使用 PHP 删除 XML 中的子项的帮助
- 使用 JavaScript 从 XML 中删除子节点
- InDesign CS6 javascript:导入 XML 并删除空白页
- 根据项目标记删除 xml 中的行
- 使用 PHP 创建、插入、更新或删除 XML
- 如何使用jQuery删除XML文件的第一行
- 删除XML字符串中的返回值
- XML通过属性值JavaScript删除节点
- 使用AngularJS中的AJAX,点击按钮即可删除XML记录
- 如何使用Jquery删除xml中的外部元素
- 使用nodeelementtree(nodejs)从xml文件中删除元素
- 使用Translate函数删除xml中的换行符,但我如何忽略某些标记
- 删除特定的xml节点Javascript
- Google Maps API v3会延迟从XML中删除标记
- Javascript DOMParser和XMLSerialier删除XML实体
- 使用Xml.parse()删除与值数组匹配的html标记和内容