Могу ли я игнорировать недопустимый символ XML с помощью встроенных в Scala обработчиков xml? - PullRequest
4 голосов
/ 10 марта 2010

У меня есть файл 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.

Нокогири Руби удалось разобрать его с недопустимым символом.

Ответы [ 3 ]

10 голосов
/ 10 марта 2010

Чтобы расширить ответ @ huynhjl: фильтр InputStream опасен, если у вас есть многобайтовые символы, например, в кодированном тексте UTF-8. Вместо этого используйте символьно-ориентированный фильтр: 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>&#x12;</root>

scala> scala.xml.XML.loadString(cleanXml) 
res14: scala.xml.Elem = <root></root>
5 голосов
/ 10 марта 2010

Интересно, допустим ли 0x12 даже в XML 1.1. См. сводку о разнице 1,0 против 1,1. В частности:

Кроме того, XML 1.1 позволяет вам есть контрольные символы в вашем документы с использованием символов Рекомендации. Это касается контроля символы с # x1 по # x1F, большинство которые запрещены в XML 1.0. это означает, что ваш документ теперь может включите символ звонка, как это: , Тем не менее, вы все еще не можете иметь эти символы появляются прямо в ваши документы; это нарушает определение типа пантомимы, используемого для XML (текст / xml).

Xerces может анализировать XML 1.1, но, похоже, ожидает, что объект &#18; вместо истинного символа 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>&#18;</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)
3 голосов
/ 10 марта 2010

0x12 действителен только в XML 1.1. Если в вашем XML-файле указана эта версия, вы можете включить поддержку обработки 1.1 в вашем SAX-парсере.

В противном случае лежащим в основе синтаксическим анализатором является, вероятно, Xerces, который, как соответствующий синтаксический анализатор XML, по-настоящему жалуется.

Если вам нужно обработать эти потоки, я бы написал оболочку InputStream или Reader вокруг моего входного файла, отфильтровал символы с недопустимыми значениями Unicode и передал бы остальные.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...