1.内容中含有xml预定好的实体,如“<”和“&”,对xml来说是禁止使用的,针对这种字符,解决方式是使用CDATA部件以\"<![CDATA[\" 标记开始,以\"]]>\"标记结束,是CDATA内部内容被解析器忽略。具体说明参考《XML CDATA是什么?》。
2.内容中含有低位非打印字符,解析时会报错:\"\"(十六进制值 0x1D)是无效的字符.加载或保存XML时引发的异常.System.ArgumentException: “”(十六进制值 0x1D)是无效的字符。
出错的原因是内容中含有低位非打印字符,处理方法是对其进行过滤,过滤方法为:
return System.Text.RegularExpressions.Regex.Replace(str,@\"[\\x00-\\x08]|[\\x0B-\\x0C]|[\\x0E-\\x1F]\";
以上两种情况,第一种较为普遍,第二种遇到情况比较少,在面对一些用户输入数据时生成xml,可以对xml结点内容执行上述过滤,以保证xml文件使用者可以正确解析xml文档。
以下是详细解释:
“”(十六进制值 0x1D)是无效的字符
加载或保存XML时引发的异常.System.ArgumentException: “”(十六进制值 0x1D)是无效的字符。
产生原因是xml文件中包含低位非打印字符造成的
处理方法:在产生xml文件的时候,过滤低位非打印字符
把一个字符串中的 低序位 ASCII 字符 替换成 &#x 字符
转换 ASCII 0 - 8 -> \0 -
转换 ASCII 11 - 12 -> -
转换 ASCII 14 - 31 -> -
简单的处理方法
return System.Text.RegularExpressions.Regex.Replace(HttpUtility.HtmlEncode(str),@\"[\\x00-\\x08]|[\\x0B-\\x0C]|[\\x0E-\\x1F]\", \"\");
======================================================================================================================================================
复杂处理
获取xml时,出现“(十六进制值 0x1F)是无效的字符之类Xml异常的解决办法2008-12-19 10:44最近做新闻采集器,需要获取很多站点的xml,加载个别站点经常出现“(十六进制值 0x1F)是无效的字符”问题,百思不的其解。对于问题站点xml的处理,开始的思路是既然直接用 XmlDocument对象的Load()方法不行,就用LoadXML() ,用HttpWebRequest 获取url读到流里再转为xml,中间可以加一些非有效字符的过滤处理,但仍然无效,仅仅解决了请求超时的问题...
问题搁置了1周后,终于在今天解决了。
其实很简单,只加一条语句就搞定了
XmlDocument doc = new XmlDocument();
doc.Normalize();
// 摘要:
// 将此 XmlNode 下子树完全深度中的所有 XmlText 节点都转换成“正常”形式,在这种形式中只有标记(即标记、注释、处理指令、CDATA
// 节和实体引用)分隔 XmlText 节点,也就是说,没有相邻的 XmlText 节点。
以下是转一位仁兄的贴:
最近碰到一个问题,我的一个把数据库中记录的信息暴露出来的Web Service调用时候出问题了。报下面的错误信息:
System.InvalidOperationException was unhandled Message=\"XML 文档(1, 823)中有错误。\" Source=\"System.Xml\" Message=\"“”(十六进制值 0x0E)是无效的字符。 行 1,位置 823。\" Source=\"System.Xml\"
当这个错误发生时,Web Service 服务器端不会有任何错误,而调用这个 Web Service 的客户端则会报上述错误。
是何原因导致的这个问题呢?
答案很简单,是WEB Service 暴露的XML文档中存在低序位非打印 ASCII 字符所致。
我们查看 Web Service 返回的XML 文档文档中,会有下面的XML文档节:其中的 就是低序位 ASCII 字符。 对应的字符如后:
<Value> 在神奇天地裏誰叱咤風雨</Value>
会导致这些问题的 低序位非打印 ASCII 字符包含以下字符:
#x0 - #x8 (ASCII 0 - 8)
#xB - #xC (ASCII 11 - 12)
#xE - #x1F (ASCII 14 - 31)
下面就是一个简单演示这个问题的控制台程序,
为了简单起见,这里没有建立 WebService, 而是把一个类XML序列化存储到文件,然后再把这个文件反序列化读取出来:
其中的这个类的Value值中,放了一个低序位非打印 ASCII 字符。
执行这个控制台程序,就会报异常。“XML 文档(3, 12)中有错误。”
using System; using System.Xml.Serialization; using System.IO; using System.Text; using System.Globalization; namespace TextSerialize { [Serializable] public class MyClass { public string Value { get; set; } } class Program { static void Main(string[] args) { string fileName = \"d:\\\\1.txt\"; MyClass c = new MyClass(); c.Value = string.Format(\"在神奇{0}天地裏誰叱咤風雨\", Convert.ToChar(14)); SaveAsXML(c, fileName, Encoding.UTF8); object o = ConvertFileToObject(fileName, typeof(MyClass), Encoding.UTF8); MyClass d = o as MyClass; if (d != null) Console.WriteLine(d.Value); else Console.WriteLine(\"null\"); Console.ReadLine(); } /// <summary> /// 序列化 /// </summary> /// <param name=\"objectToConvert\"></param> /// <param name=\"path\"></param> /// <param name=\"encoding\"></param> public static void SaveAsXML(object objectToConvert, string path, Encoding encoding) { if (objectToConvert != null) { Type t = objectToConvert.GetType(); XmlSerializer ser = new XmlSerializer(t); using (StreamWriter writer = new StreamWriter(path, false, encoding)) { ser.Serialize(writer, objectToConvert); writer.Close(); } } } /// <summary> /// 反序列化 /// </summary> /// <param name=\"path\"></param> /// <param name=\"objectType\"></param> /// <param name=\"encoding\"></param> /// <returns></returns> public static object ConvertFileToObject(string path, Type objectType, Encoding encoding) { object convertedObject = null; if (!string.IsNullOrEmpty(path)) { XmlSerializer ser = new XmlSerializer(objectType); using (StreamReader reader = new StreamReader(path, encoding)) { convertedObject = ser.Deserialize(reader); reader.Close(); } } return convertedObject; } } }
上面提到的Web Service 的那个问题,跟这个演示程序是一样的。
我们需要被序列化的内容中,存在 低序位非打印 ASCII 字符 时, .net 会给我们正常序列化, 会自动把 低序位非打印 ASCII 字符 转换成 &#x 编码的字符(这个XML规范中要求这么做的)。</p> <p>但是,反序列化时候,如果需要反序列化的内容如果存在 &#x 编码的字符(映射到低序位非打印 ASCII 字符),则反序列化就会出错。</p> <p><br /> <strong>如果解决这个问题呢?</strong></p> <p>当然,最彻底的解决方法是修改反序列化的代码,让这些字符不会出错。但这个东西很多时候不归我们控制。这个方案不可行。</p> <p>下一个方案就是剔除这些捣乱的字符。</p> <p>我这里要给出的方案,是对这些字符序列化时作一次预处理,反序列化时,作一次反向处理。<br /> 这里为了演示的更有意义,我这里处理逻辑就是把 低序位非打印 ASCII 字符 转换成 &#x 编码的字符 ,和把&#x 编码的字符 转换成 低序位非打印 ASCII 字符。 <br /> 这样就可以使用我这里提供的函数,实现更多的处理逻辑。这两个函数的代码如下:</p> <p> </p> <div class=\"phpstudycode\"> <pre class=\"brush:csharp;\"> /// <summary> /// 把一个字符串中的 低序位 ASCII 字符 替换成 &#x 字符 /// 转换 ASCII 0 - 8 -> � -  /// 转换 ASCII 11 - 12 ->  -  /// 转换 ASCII 14 - 31 ->  -  /// </summary> /// <param name=\"tmp\"></param> /// <returns></returns> public static string ReplaceLowOrderASCIICharacters(string tmp) { StringBuilder info = new StringBuilder(); foreach (char cc in tmp) { int ss = (int)cc; if (((ss >= 0) && (ss <= 8)) || ((ss >= 11) && (ss <= 12)) || ((ss >= 14) && (ss <= 32))) info.AppendFormat(\"&#x{0:X};\", ss); else info.Append(cc); } return info.ToString(); } /// <summary> /// 把一个字符串中的下列字符替换成 低序位 ASCII 字符 /// 转换 � -  -> ASCII 0 - 8 /// 转换  -  -> ASCII 11 - 12 /// 转换  -  -> ASCII 14 - 31 /// </summary> /// <param name=\"input\"></param> /// <returns></returns> public static string GetLowOrderASCIICharacters(string input) { if (string.IsNullOrEmpty(input)) return string.Empty; int pos, startIndex = 0, len = input.Length; if (len <= 4) return input; StringBuilder result = new StringBuilder(); while ((pos = input.IndexOf(\"&#x\", startIndex)) >= 0) { bool needReplace = false; string rOldV = string.Empty, rNewV = string.Empty; int le = (len - pos < 6) ? len - pos : 6; int p = input.IndexOf(\";\", pos, le); if (p >= 0) { rOldV = input.Substring(pos, p - pos + 1); // 计算 对应的低位字符 short ss; if (short.TryParse(rOldV.Substring(3, p - pos - 3), NumberStyles.AllowHexSpecifier, null, out ss)) { if (((ss >= 0) && (ss <= 8)) || ((ss >= 11) && (ss <= 12)) || ((ss >= 14) && (ss <= 32))) { needReplace = true; rNewV = Convert.ToChar(ss).ToString(); } } pos = p + 1; } else pos += le; string part = input.Substring(startIndex, pos - startIndex); if (needReplace) result.Append(part.Replace(rOldV, rNewV)); else result.Append(part); startIndex = pos; } result.Append(input.Substring(startIndex)); return result.ToString(); }</pre> </div> <p><br /> 这样,我们这个演示程序的 Main 函数修改为下面的代码,也不会有任何错误发生。</p> <div class=\"phpstudycode\"> <pre class=\"brush:csharp;\"> static void Main(string[] args) { Console.WriteLine(GetLowOrderASCIICharacters(\"123456񐀀\")); Console.WriteLine(GetLowOrderASCIICharacters(\"123456\")); Console.WriteLine(GetLowOrderASCIICharacters(\"\")); Console.WriteLine(GetLowOrderASCIICharacters(\"0123 456789\")); Console.WriteLine(GetLowOrderASCIICharacters(\"\\f\")); Console.WriteLine(GetLowOrderASCIICharacters(\" =-1\")); Console.WriteLine(GetLowOrderASCIICharacters(\" \")); Console.WriteLine(GetLowOrderASCIICharacters(\" \")); string fileName = \"d:\\\\1.txt\"; MyClass c = new MyClass(); c.Value = string.Format(\"在神奇{0}天地裏誰叱咤風雨\", Convert.ToChar(14)); c.Value = ReplaceLowOrderASCIICharacters(c.Value); SaveAsXML(c, fileName, Encoding.UTF8); object o = ConvertFileToObject(fileName, typeof(MyClass), Encoding.UTF8); MyClass d = o as MyClass; if (d != null) { d.Value = GetLowOrderASCIICharacters(d.Value); Console.WriteLine(d.Value); } else Console.WriteLine(\"null\"); Console.ReadLine(); }</pre> </div> </div> </section> <script type=\"text/javascript\"> (function() { var s = \"_\" + Math.random().toString(36).slice(2); document.write(\'<div style=\"\" id=\"\' + s + \'\"></div>\'); (window.slotbydup = window.slotbydup || []).push({ id: \"u4263905\", container: s }); })(); </script> <section class=\"xgwz\"> <b>【热门文章】</b> <ul> <li><a href=\"/b.php/58001.html\">浅析node.js中close事件</a></li><li><a href=\"/b.php/58002.html\">javascript模拟订火车票和退票示例</a></li><li><a href=\"/b.php/58003.html\">php判断并删除空目录及空子目录的方法</a></li><li><a href=\"/b.php/58004.html\">win10无法打开这个应用解决办法</a></li><li><a href=\"/b.php/58005.html\">浅析XMLHttpRequest的缓存问题</a></li><li><a href=\"/b.php/58006.html\">一系列Bootstrap导航条使用方法分享</a></li><li><a href=\"/b.php/58007.html\">JS简单获取及显示当前时间的方法</a></li><li><a href=\"/b.php/58008.html\">C#实现自定义定时组件的方法</a></li><li><a href=\"/b.php/58010.html\">Win7/Win8.1用户升级Win10 这个通知是升级Win10通行证</a></li><li><a href=\"/b.php/58011.html\">Android WebView 优化之路</a></li><li><a href=\"/b.php/58012.html\">JavaScript的作用域和块级作用域概念理解</a></li><li><a href=\"/b.php/58013.html\">mysql常用监控脚本命令整理</a></li><li><a href=\"/b.php/58014.html\">JS实现冒泡排序,插入排序和快速排序并排序输出</a></li><li><a href=\"/b.php/58015.html\">asp.net微信开发(永久素材管理)</a></li><li><a href=\"/b.php/58016.html\">浅析mongodb中group分组</a></li><li><a href=\"/b.php/58017.html\">Ubuntu系统上使用LVM调整硬盘分区的教程</a></li><li><a href=\"/b.php/58018.html\">iOS应用开发中UITabBarController标签栏控制器使用进阶</a></li><li><a href=\"/b.php/58019.html\">php验证session无效的解决方法</a></li><li><a href=\"/b.php/58020.html\">Android中AutoCompleteTextView与TextWatcher结合小实例</a></li><li><a href=\"/b.php/58021.html\">C#抽象类和接口的区别分析</a></li><li><a href=\"/b.php/58022.html\">CentOS 一键配置rsync服务器脚本</a></li><li><a href=\"/b.php/58023.html\">oracle远程连接服务器出现 ORA-12170 TNS:连接超时 解决办法</a></li><li><a href=\"/b.php/58024.html\">Linux查看系统信息的常用命令</a></li><li><a href=\"/b.php/58025.html\">解析C++编程中异常相关的堆栈展开和throw()异常规范</a></li></ul> </section> <section class=\"xgwz\"> <b>【热门文章】</b> <ul> <li><a href=\"/c.php/35619.html\">angular 这段代码的作用是什么?</a></li><li><a href=\"/c.php/35620.html\"><?php </script>?>不报错</a></li><li><a href=\"/c.php/35621.html\">ruby一道循环算法题:不同ID出现次数</a></li><li><a href=\"/c.php/35622.html\">企业内部科学上网解决方案?</a></li><li><a href=\"/c.php/35623.html\">聊聊APP接口版本 开发和维护</a></li><li><a href=\"/c.php/35624.html\">脚本从windows上传到linux无法执行</a></li><li><a href=\"/c.php/35625.html\">这样一段python,如何转成php实现?</a></li><li><a href=\"/c.php/35626.html\">avalon.js 里面有谁写过扩展的UI控件</a></li><li><a href=\"/c.php/35627.html\">vuejs构建非单页应用</a></li><li><a href=\"/c.php/35628.html\">ADB shell input 中文问题</a></li><li><a href=\"/c.php/35629.html\">用原生JavaScript实现冒泡排序的可视化,setTimeout如何使用?</a></li><li><a href=\"/c.php/35630.html\">buf.toString([encoding[, start[, end]]])</a></li><li><a href=\"/c.php/35631.html\">angularjs directive link 属性 问题</a></li><li><a href=\"/c.php/35632.html\">怎样用css获取列其他项表中除了前三项以外的</a></li><li><a href=\"/c.php/35633.html\">ios 有人用过JSPatch 这个动态更新iOS APP 感觉如何 能跟我说一下吗</a></li><li><a href=\"/c.php/35634.html\">让ie8实现placeholder属性效果,value值的默认颜色怎么设置才能和输入时的颜色不冲突?</a></li><li><a href=\"/c.php/35635.html\">python:requests获取网页源码的时候乱码</a></li><li><a href=\"/c.php/35636.html\">网页关闭时如何新开一个页面</a></li><li><a href=\"/c.php/35637.html\">在helper里写了一个方法,想用一个button去触发执行,请问用button_to 还是link_to, 后边的参数应该如何配。</a></li><li><a href=\"/c.php/35638.html\">如何批量删除doker在构建时产生的一些中间镜像?</a></li></ul> </section> <section class=\"cont pl\" id=\"comment\"><b></b> <div id=\"SOHUCS\" sid=\"art_104965\"></div> </section> <div class=\"search\"> <form action=\"http://zhannei.baidu.com/cse/search\" method=\"get\" target=\"_blank\" class=\"bdcs-search-form\" id=\"bdcs-search-form\"> <input name=\"s\" value=\"12351952642737355179\" type=\"hidden\"> <input name=\"entry\" value=\"1\" type=\"hidden\"> <input name=\"ie\" value=\"gbk\" type=\"hidden\"> <input name=\"nsid\" value=\"1\" type=\"hidden\"> <input type=\"text\" placeholder=\"请输入您感兴趣的关键字\" value=\"\" id=\"search_txt1\" maxlength=\"18\" class=\"search_txt\" name=\"q\"> <input class=\"search_btn\" value=\"搜 索\" type=\"submit\"> </form> </div> <nav class=\"nav-foot\"> <ul> <li><a href=\"/jiaotong/huoche/\">火车</a></li> <li><a href=\"/jiaotong/gaotie/\">高铁</a></li> <li><a href=\"/jiaotong/qiche/\">汽车</a></li> <li><a href=\"/jiaotong/gongjiao/\">公交</a></li> <li><a href=\"/jiaotong/zijia/\">自驾</a></li> <li><a href=\"/jiaotong/licheng/\">里程</a></li> <li> <a href=\"/jiaotong/jingdian/\">景点</a></li> <li><a href=\"/jiaotong/gonglue/\">攻略</a></li> <li><a href=\"/jiaotong/wen/\">问路</a></li> <li><a href=\"/\">计算机</a></li> </ul> <ul> <li><a href=\"/\">首页</a></li> <li><a href=\"/jiaotong/huoche/\">火车</a></li> <li><a href=\"/jiaotong/gaotie/\">高铁</a></li> <li><a href=\"/jiaotong/qiche/\">汽车</a></li> <li><a href=\"/jiaotong/gongjiao/\">公交</a></li> </ul> </nav> <footer class=\"footer-min\"> <div class=\"app\"> <a href=\"javascript:void(0)\" class=\"pc\">电脑版</a> - <a href=\"/\">返回首页</a></div> <div class=\"copyright\">Copyright ©2017 <a href=\"/\">交通频道</a> All Rights Reserved</div> </footer> <div class=\"clearfix\"></div> <div class=\"asd\"><span id=\"asd-footer\" class=\"jbTestPos\"><script>gx(4);</script></span></div> <script> var path_url=\"/b.php/90458.html\"; </script> <script type=\"text/javascript\" src=\"/img/jquery-1.10.2.min.js\"></script> <script type=\"text/javascript\" src=\"/img/menuclick.js\"></script> <br> <script> var _hmt = _hmt || []; (function() { var hm = document.createElement(\"script\"); hm.src = \"https://hm.baidu.com/hm.js?4e18701aa680bab2e8eb968e32500cf0\"; var s = document.getElementsByTagName(\"script\")[0]; s.parentNode.insertBefore(hm, s); })(); </script> </div> </body> </html>
本文地址:https://www.stayed.cn/item/7616
转载请注明出处。
本站部分内容来源于网络,如侵犯到您的权益,请 联系我