我有一个xml文件(来自联邦政府的data.gov),我正在尝试用scala的xml处理程序读取它。
val loadnode = scala.xml.XML.loadFile(filename) 显然,有一个无效的xml字符。是否有忽略无效字符的选项?还是我唯一的选择是先把它清理干净?
org.xml.sax.SAXParseException: An invalid XML character (Unicode: 0x12) was found in the element content of the document.Ruby的nokogiri能够用无效字符解析它。
发布于 2010-03-10 13:32:57
我想知道0x12是否在XML1.1中也有效。查看1.0版与1.1版的summary差异。特别是:
此外,XML1.1还允许通过使用字符引用在文档中使用控制字符。这与控制字符#x1到#x1F有关,其中大多数字符在XML 1.0中是被禁止的。这意味着您的文档现在可以包含钟形字符,如下所示:。但是,您仍然不能让这些字符直接出现在文档中;这违反了用于XML (text/xml)的mime类型的定义。
Xerces可以解析XML1.1,但似乎需要实体,而不是真正的0x12字符:
val s = "<?xml version='1.1'?><root>\u0012</root>"
// causes An invalid XML character (Unicode: 0x12)
//XML.loadXML(xml.Source.fromString(s), XML.parser)
val u = "<?xml version='1.1'?><root></root>"
val v = XML.loadXML(xml.Source.fromString(u), XML.parser)
println(v) // works正如lavinio所建议的,您可以过滤掉无效的字符。这在Scala中不会占用太多代码行:
val in = new InputStream {
val in0 = new FileInputStream("invalid.xml")
override def read():Int = in0.read match { case 0x12=> read() case x=> x}
}
val x = XML.load(in)发布于 2010-03-10 14:34:04
扩展@huynhjl的答案:如果您有多字节字符,例如在UTF8编码的文本中,InputStream过滤器是危险的。相反,使用面向字符的过滤器:FilterReader。或者,如果文件足够小,则加载到String中并替换其中的字符。
scala> val origXml = "<?xml version='1.1'?><root>\u0012</root>"
origXml: java.lang.String = <?xml version='1.1'?><root></root>
scala> val cleanXml = xml flatMap {
case x if Character.isISOControl(x) => "&#x" + Integer.toHexString(x) + ";"
case x => Seq(x)
}
cleanXml: String = <?xml version='1.1'?><root></root>
scala> scala.xml.XML.loadString(cleanXml)
res14: scala.xml.Elem = <root></root>发布于 2010-03-10 11:03:10
0x12仅在XML 1.1中有效。如果XML文件说明了该版本,则可以在SAX解析器中启用1.1处理支持。
否则,底层解析器可能是Xerces,作为符合规范的XML解析器,Xerces理所当然地在抱怨。
如果必须处理这些流,我会在输入文件周围编写一个包装器InputStream或读取器,过滤掉具有无效Unicode值的字符,然后将其余的传递出去。
https://stackoverflow.com/questions/2413939
复制相似问题