`

检查xml文件中包含非法xml字符的个数(java实现)

    博客分类:
  • xml
 
阅读更多

xml中需要过滤的字符分为两类,一类是不允许出现在xml中的字符,这些字符不在xml的定义范围之内。另一类是xml自身要使用的字符,如果内容中有这些字符则需被替换成别的字符。

第一类字符
对于第一类字符,我们可以通过W3C的XML文档来查看都有哪些字符不被允许出现在xml文档中。
XML允许的字符范围是“#x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]”。因此我们可以把这个范围之外的字符过滤掉。
需要过滤的字符的范围为:
\\x00-\\x08
\\x0b-\\x0c
\\x0e-\\x1f
利用.NET中 Regex的 Replace 方法对字符串中在这3个范围段的字符进行替换,如:
string content = “as fas fasfadfasdfasdf<234234546456″;
content = Regex.Replace(content, “[\\x00-\\x08\\x0b-\\x0c\\x0e-\\x1f]“, “*”);
Response.Write(content);
利用PB8,对这个范围的字符进行过滤如下:
string content = “as fas fasfadfasdfasdf<234234546456″;
int i_count_eliminate=30
char i_spechar_eliminate[]={“~001″ , “~002″ , &
“~003″ , “~004″ , “~005″ , “~006″ , “~007″ , &
“~008″ , “~011″ , “~012″ , “~014″ , “~015″ , &
“~016″ , “~017″ , “~018″ , “~019″ , “~020″ , &
“~021″ , “~022″ , “~023″ , “~024″ , “~025″ , &
“~026″ , “~027″ , “~028″ , “~029″ , “~030″ , &
“~031″ , ‘”‘    , “`”  } //需要消除的字符,将直接替换为空
for vi=1 to i_count_eliminate
vpos=1
vlen=lenw(i_spechar_eliminate[vi])
do while true
vpos = posw(content,i_spechar_eliminate[vi],vpos)
if vpos<1 then exit
content=replacew(content,vpos,vlen,”")
loop
next
第二类字符
对于第二类字符一共有5个,如下:
字符                HTML字符        字符编码
和(and) &        &amp;            &#38;
单引号  ’ &apos;            &#39;
双引号  ”          &quot;            &#34;
大于号  >        &gt;                  &#62;
小于号  <        &lt;                   &#60;
我们只需要对这个五个字符,进行相应的替换就可以了

   

xml支持的字符范围

Character Range
[2]     Char     ::=     #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]  /* any Unicode character, excluding the surrogate blocks, FFFE, and FFFF. */

any Unicode character, excluding the surrogate blocks, FFFE, and FFFF.
意思是xml支持的字符范围是任何unicode字符,排除surrogate blocks(代理块),  FFFE和 FFFF.

其中0xD800 至 0xDBFF(高代理high surrogate) 和 0xDC00 至 0xDFFF(低代理low surrogate)被称为surrogate blocks(代理块)

代理块是为了表示增补字符 增补字符是在 [#x10000-#x10FFFF] 范围之间的字符

增补字符是扩展16位unicode不能表示的字符。Unicode 最初设计是作为一种固定宽度的 16 位字符编码。16 位编码的所有 65,536 个字符并不能完全表示全世界所有正在使用或曾经使用的字符。于是,Unicode 标准扩展到包含多达 1,112,064 个字符,这些扩展字符就是增补字符。

XMLCheck用于检查xml文件中包含非法xml字符的个数。

使用方法 XMLCheck filename

import java.io.*;

public class XMLCheck {

 /**
  * @author lxn
  *
  */
 public static void main(String[] args) throws IOException{
 
  if(args.length == 0)
  {
   System.out.print("Usage: XMLCheck filename");
   return;
  }
 
 
  File xmlFile = new File(args[0]);
  if(!xmlFile.exists())
  {
   System.out.print("File not exist");
   return;
  }
 
  //输入xml文件
  BufferedReader  in = new BufferedReader(new FileReader(xmlFile));
  String s;
  StringBuilder xmlSb = new StringBuilder();
  //xml文件转换成String
  while((s = in.readLine())!=null)
   xmlSb.append(s+"\n");
  in.close();
  String xmlString = xmlSb.toString();
  // TODO Auto-generated method stub
  //无特殊字符的
  //int i = checkCharacterData("<?xml version=\"1.0\" encoding=\"gbk\"?><CC>卡号</CC>");
  //有特殊字符的
  //int i = checkCharacterData("<?xml version=\"1.0\" encoding=\"gbk\"?><CC>\u001E卡号</CC>");
 
  int errorChar = checkCharacterData(xmlString);
  System.out.println("This XML file contain "+errorChar+" errorChar.");
 }
 
 //判断字符串中是否有非法字符
 public static int checkCharacterData(String text){
  int errorChar=0;
  if(text==null){
   return errorChar;
  }
  char[] data = text.toCharArray();
  for(int i=0,len=data.length;i<len;i++){
   char c = data[i];
   int result=c;
   //先判断是否在代理范围(surrogate blocks)
   //增补字符编码为两个代码单元,
   //第一个单元来自于高代理(high surrogate)范围(0xD800 至 0xDBFF),
   //第二个单元来自于低代理(low surrogate)范围(0xDC00 至 0xDFFF)。
   if(result>=0xD800 && result<=0xDBFF){
    //解码代理对(surrogate pair)
    int high = c;
    try{
     int low=text.charAt(i+1);
   
     if(low<0xDC00||low>0xDFFF){
      char ch=(char)low;
     }
     //unicode说明定义的算法 计算出增补字符范围0x10000 至 0x10FFFF
     //即若result是增补字符集,应该在0x10000到0x10FFFF之间,isXMLCharacter中有判断
     result = (high-0xD800)*0x400+(low-0xDC00)+0x10000;
     i++;
    }
    catch(Exception e){
     e.printStackTrace();
    }
   }
   if(!isXMLCharacter(result)){
     errorChar++;
   }
  }
   return errorChar;
 }
 private static boolean isXMLCharacter(int c){
  //根据xml规范中的Character Range检测xml不支持的字符
  if(c <= 0xD7FF){
   if(c >= 0x20)return true;
   else{
    if (c == '\n') return true;
    if (c == '\r') return true;
    if (c == '\t') return true;
    return false;
   }
  }
  if (c < 0xE000) return false;  if (c <= 0xFFFD) return true;
  if (c < 0x10000) return false;  if (c <= 0x10FFFF) return true;
    return false;
 }

}

分享到:
评论

相关推荐

    Xpath读取xml文件,实现文件缓存。

    例如,在Java中,可以使用`javax.xml.xpath`包中的`XPath`和`XPathFactory`类来执行XPath表达式;在Python中,可以使用`lxml`库;在JavaScript中,可以借助`DOMParser`和`XPathEvaluator`。同时,可以结合`java.util...

    解决XML节点删除后会留下一个空节点的问题

    4. **使用字符串操作**:如果可能,可以将XML转换为字符串,进行字符串操作来删除节点,然后再将结果转换回XML。这种方法需谨慎处理,因为它可能破坏XML的结构。 5. **选择合适的解析库**:不同编程语言的XML库处理...

    跨平台解析XML文件 XmlNode V1.01测试版

    为保证xml文件格式正确,将自动在Xml中添加声明 ***************************************************/ bool SaveFile(string sPath); /*************************************************** Type: public ...

    Java开发实战1200例(第1卷).(清华出版.李钟尉.陈丹丹).part3

    本书是第II卷,以开发人员在项目开发中经常遇到的问题和必须掌握的技术为中心,介绍了应用Java进行桌面程序开发各个方面的知识和技巧,主要包括Java语法与面向对象技术、Java高级应用、窗体与控件应用、文件操作...

    Java面试宝典-经典

    23、java中实现多态的机制是什么? 17 24、abstract class和interface有什么区别? 17 25、abstract的method是否可同时是static,是否可同时是native,是否可同时是synchronized? 18 26、什么是内部类?Static Nested ...

    XPath语法详解xml开发必备

    - **函数**:XPath包含许多内置函数,如 `text()` 返回节点的文本内容,`count(nodeSet)` 计算节点集的个数,`contains(string1, string2)` 检查字符串1是否包含字符串2。 6. **通配符和运算符** - **通配符**:`...

    stat()—获取文件状态

    该结构体 `struct stat` 中包含了文件的详细信息,包括: * `dev_t st_dev`: 文件的设备编号 * `ino_t st_ino`: 文件的 i-node * `mode_t st_mode`: 文件的类型和存取权限 * `nlink_t st_nlink`: 连到该文件的硬...

    Python Cookbook

    1.8 检查字符串中是否包含某字符集合中的字符 15 1.9 简化字符串的translate方法的使用 18 1.10 过滤字符串中不属于指定集合的字符 20 1.11 检查一个字符串是文本还是二进制 23 1.12 控制大小写 25 1.13 访问子...

    最新Java面试宝典pdf版

    23、java中实现多态的机制是什么? 17 24、abstract class和interface有什么区别? 17 25、abstract的method是否可同时是static,是否可同时是native,是否可同时是synchronized? 18 26、什么是内部类?Static Nested ...

    java面试宝典2012

    23、java中实现多态的机制是什么? 18 24、abstract class和interface有什么区别? 18 25、abstract的method是否可同时是static,是否可同时是native,是否可同时是synchronized? 20 26、什么是内部类?Static Nested ...

    Java面试宝典2012版

    23、java中实现多态的机制是什么? 17 24、abstract class和interface有什么区别? 17 25、abstract的method是否可同时是static,是否可同时是native,是否可同时是synchronized? 18 26、什么是内部类?Static ...

    分页通过下拉框选择每页显示的个数

    例如,使用`LIMIT`和`OFFSET`关键字在MySQL中进行分页,或者在SQL中使用`ROW_NUMBER()`函数配合`OVER()`在SQL Server中实现。 4. **模糊查询**: 模糊查询允许用户输入包含通配符的查询条件,比如关键词的前后可以...

    Python每日一题.pdf

    7. XML和Excel文件操作:题目0014、0015、0016、0017、0018、0019涵盖了XML和Excel文件操作的知识点,如将数据写到XML文件中、读取和写入Excel文件等,涉及到xml.etree.ElementTree和openpyxl库的使用。 本资源摘要...

    2018年java技术面试题整理

    Java 技术面试题整理 以下是 Java 技术面试题整理的知识点: 1. Servlet 执行流程: * 客户端发出 HTTP 请求 * Web 服务器将请求转发到 Servlet 容器 * Servlet 容器解析 URL 并根据 web.xml 找到相应的 Servlet ...

Global site tag (gtag.js) - Google Analytics