SparkSQL with databricks xml lib: 'Malformed row'/UnboundPrefix on a valid xml
SparkSQL with databricks xml lib: 'Malformed row'/UnboundPrefix on a valid xml
假设我 运行在 Oracle JDK 1.8(内部版本 1.8.0_65-b17)上 运行ning Spark 1.6.0 在一个 ipython 笔记本会话中开始于以下内容行:
PYSPARK_DRIVER_PYTHON=ipython PYSPARK_DRIVER_PYTHON_OPTS=notebook pyspark --packages com.databricks:spark-xml_2.10:0.3.1z
所以我包含了 databricks 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$$anonfun$apply.apply(InferSchema.scala:101)
at com.databricks.spark.xml.util.InferSchema$$anonfun$$anonfun$apply.apply(InferSchema.scala:83)
...
指的是这行代码:https://github.com/databricks/spark-xml/blob/master/src/main/scala/com/databricks/spark/xml/util/InferSchema.scala#L101。这显然是上面的一些 javax.xml.stream 类 抛出的 XMLStreamException 的情况。
不幸的是,处理程序忽略了异常的详细信息,因此我无法判断该行到底出了什么问题。但是,从属性中删除名称空间(即 r:id
变为 id
)会使它消失。
我觉得我遇到了一些常见的陷阱,只需要知道是哪一个。
UPD:我用调试语句编译了我自己的 databricks lib jar,结果是,它是关于未绑定前缀的:
: 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)
这是什么原因,我该如何解决?
如您在 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 文件,但我认为我们应该考虑一个更好的解决方案来处理命名空间。
假设我 运行在 Oracle JDK 1.8(内部版本 1.8.0_65-b17)上 运行ning Spark 1.6.0 在一个 ipython 笔记本会话中开始于以下内容行:
PYSPARK_DRIVER_PYTHON=ipython PYSPARK_DRIVER_PYTHON_OPTS=notebook pyspark --packages com.databricks:spark-xml_2.10:0.3.1z
所以我包含了 databricks 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$$anonfun$apply.apply(InferSchema.scala:101)
at com.databricks.spark.xml.util.InferSchema$$anonfun$$anonfun$apply.apply(InferSchema.scala:83)
...
指的是这行代码:https://github.com/databricks/spark-xml/blob/master/src/main/scala/com/databricks/spark/xml/util/InferSchema.scala#L101。这显然是上面的一些 javax.xml.stream 类 抛出的 XMLStreamException 的情况。
不幸的是,处理程序忽略了异常的详细信息,因此我无法判断该行到底出了什么问题。但是,从属性中删除名称空间(即 r:id
变为 id
)会使它消失。
我觉得我遇到了一些常见的陷阱,只需要知道是哪一个。
UPD:我用调试语句编译了我自己的 databricks lib jar,结果是,它是关于未绑定前缀的:
: 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)
这是什么原因,我该如何解决?
如您在 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 文件,但我认为我们应该考虑一个更好的解决方案来处理命名空间。