• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号
您的位置:首页 > 程序设计 >C#教程 > c#中XML解析文件出错解决方法

c#中XML解析文件出错解决方法

作者: 字体:[增加 减小] 来源:互联网 时间:2017-05-28

通过本文主要向大家介绍了c#xml文件读写,c#读取xml文件,c#创建xml文件,c#生成xml文件,c#解析xml文件等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

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 -> � - 
转换 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"

</div>

当这个错误发生时,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;
}
}
}
</div>

上面提到的Web Service 的那个问题,跟这个演示程序是一样的。

我们需要被序列化的内容中,存在 低序位非打印 ASCII 字符 时, .net 会给我们正常序列化, 会自动把 低序位非打印 ASCII 字符 转换成 &#x 编码的字符(这个XML规范中要求这么做的)。

但是,反序列化时候,如果需要反序列化的内容如果存在 &#x 编码的字符(映射到低序位非打印 ASCII 字符),则反序列化就会出错。


如果解决这个问题呢?

当然,最彻底的解决方法是修改反序列化的代码,让这些字符不会出错。但这个东西很多时候不归我们控制。这个方案不可行。

下一个方案就是剔除这些捣乱的字符。

我这里要给出的方案,是对这些字符序列化时作一次预处理,反序列化时,作一次反向处理。
这里为了演示的更有意义,我这里处理逻辑就是把 低序位非打印 ASCII 字符 转换成 &#x 编码的字符 ,和把&#x 编码的字符 转换成 低序位非打印 ASCII 字符。
这样就可以使用我这里提供的函数,实现更多的处理逻辑。这两个函数的代码如下:

       

/// <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, startInde



 
分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

  • 读写XML文件的内容并将其显示在ListView控件上的方法
  • C#代码操作XML进行增、删、改操作
  • C#简单读写txt文件的方法
  • C#实现的xml操作类完整实例
  • C# XML序列化方法及常用特性总结分析
  • C#进行文件读写、创建、复制、移动、删除的方法
  • C#自定义处理xml数据类实例
  • C#递归读取XML菜单数据的方法
  • C#实现提高xml读写速度的方法
  • C#实现对象XML序列化的方法

相关文章

  • 2017-05-28C#控制台程序使用Log4net日志组件详解
  • 2017-05-28C#读取配置文件的方法汇总
  • 2017-05-28List<>中Find的用法小结
  • 2017-05-28C#转换日期类型实例
  • 2017-05-28C#中比较常用的DateTime结构的使用方法
  • 2017-05-28c# winform读取xml文件创建菜单的代码
  • 2017-05-28c# 共享状态的文件读写实现代码
  • 2017-05-28c# 图片加密解密的实例代码
  • 2017-05-28C#用Activex实现Web客户端读取RFID功能的代码
  • 2017-05-28C#中常使用进度条的代码

文章分类

  • JavaScript
  • ASP.NET
  • PHP
  • 正则表达式
  • AJAX
  • JSP
  • ASP
  • Flex
  • XML
  • 编程技巧
  • Android
  • swift
  • C#教程
  • vb
  • vb.net
  • C语言
  • Java
  • Delphi
  • 易语言
  • vc/mfc
  • 嵌入式开发
  • 游戏开发
  • ios
  • 编程问答
  • 汇编语言
  • 微信小程序
  • 数据结构
  • OpenGL
  • 架构设计
  • qt
  • 微信公众号

最近更新的内容

    • C#实现系统托盘通知的方法
    • C#访问命令行的两种方法
    • C# 6.0 的知识梳理
    • C#--微信小程序-跳一跳辅助工具源码
    • C#/Java连接sqlite与使用技巧
    • C#在WinForm中使用WebKit传递js对象实现与网页交互的方法
    • C#使用ODBC与OLEDB连接数据库的方法示例
    • c#重写TabControl控件实现关闭按钮的方法
    • 浅谈c#.net中巧用ToString()将日期转成想要的格式
    • C#对文件/文件夹操作代码汇总

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有