SparkSQL с блоками данных xml lib: "Неверно сформированная строка" /UnboundPrefix в действительном xml
Предположим, что я запускаю Spark 1.6.0 на Oracle JDK 1.8 (сборка 1.8.0_65-b17) в сеансе ipython notebook, который начинается со следующей строки:
PYSPARK_DRIVER_PYTHON=ipython PYSPARK_DRIVER_PYTHON_OPTS=notebook pyspark --packages com.databricks:spark-xml_2.10:0.3.1z
Поэтому я включил пакет spark-xml для блоков данных ( https://github.com/databricks/spark-xml). Далее я собираюсь запустить следующий код против pyspark:
dmoz = '/Users/user/dummy.xml'
v=sqlContext.read.format('com.databricks.spark.xml').options(rowTag='Topic', failFast=True).load(dmoz)
print v.schema
где dummy.xml содержит этот крошечный фрагмент дампа DMOZ ( http://rdf.dmoz.org/):
<?xml version="1.0" encoding="UTF-8"?>
<RDF xmlns:r="http://www.w3.org/TR/RDF/" xmlns:d="http://purl.org/dc/elements/1.0/" xmlns="http://dmoz.org/rdf/">
<!-- Generated at 2016-01-24 00:05:51 EST from DMOZ 2.0 -->
<Topic r:id="">
<catid>1</catid>
</Topic>
</RDF>
Который проверяет любой валидатор, который мне удалось найти. И результат:
...
Py4JJavaError: An error occurred while calling o82.load.
: org.apache.spark.SparkException: Job aborted due to stage failure: Task 0 in stage 1.0 failed 1 times, most recent failure: Lost task 0.0 in stage 1.0 (TID 1, localhost): java.lang.RuntimeException: Malformed row (failing fast): <Topic r:id=""> <catid>1</catid> </Topic>
at com.databricks.spark.xml.util.InferSchema$$anonfun$3$$anonfun$apply$2.apply(InferSchema.scala:101)
at com.databricks.spark.xml.util.InferSchema$$anonfun$3$$anonfun$apply$2.apply(InferSchema.scala:83)
...
Это относится к этой строке кода: https://github.com/databricks/spark-xml/blob/master/src/main/scala/com/databricks/spark/xml/util/InferSchema.scala. Это, очевидно, случай исключения XMLStreamException, которое выдают некоторые классы javax.xml.stream, описанные выше.
К сожалению, детали исключения исключаются обработчиком, поэтому я не могу сказать, что именно не так со строкой. Тем не менее, удаление пространства имен из атрибутов (т.е. r:id
становится просто id
) заставляет это уйти. Я чувствую, что попал в какую-то распространенную ловушку, просто нужно знать, какая именно
UPD: я скомпилировал свой собственный jar библиотеки databricks с операторами debug и выяснил, что речь идет о несвязанном префиксе:
: org.apache.spark.SparkException: Job aborted due to stage failure: Task 0 in stage 1.0 failed 1 times, most recent failure: Lost task 0.0 in stage 1.0 (TID 1, localhost): javax.xml.stream.XMLStreamException: ParseError at [row,col]:[1,16]
Message: http://www.w3.org/TR/1999/REC-xml-names-19990114#AttributePrefixUnbound?Topic&r:id&r
at com.sun.org.apache.xerces.internal.impl.XMLStreamReaderImpl.next(XMLStreamReaderImpl.java:596)
В чем причина и как мне это исправить?
1 ответ
Как вы описали в https://github.com/databricks/spark-xml/issues/74, это ошибка и проблема.
Я могу воспроизвести эту ошибку, запустив ниже:
val testFile = "path-for-xml"
sqlContext.xmlFile(testFile, rowTag = "Topic").show()
Консольный вывод был
11:25:32.517 WARN com.databricks.spark.xml.util.InferSchema$: Dropping malformed row: <Topic r:id=""> <catid>1</catid> </Topic>
root
Я открыл PR для этого, https://github.com/databricks/spark-xml/pull/75.
В настоящее время я представил PR для этой библиотеки, чтобы игнорировать пространства имен, но, возможно, должны быть некоторые варианты, чтобы справиться с этим.
Так что в любом случае можно было бы прочитать файл XML в следующем выпуске, но я думаю, что нам следует подумать о лучшем решении для обработки пространств имен.