Läsa och skriva XML-data med hjälp av spark-xml
biblioteket
Viktigt!
Den här dokumentationen har dragits tillbaka och kanske inte uppdateras. De produkter, tjänster eller tekniker som nämns i innehållet är inte officiellt godkända eller testade av Databricks.
Stöd för internt XML-filformat är tillgängligt som en offentlig förhandsversion. Se Läsa och skriva XML-filer.
Den här artikeln beskriver hur du läser och skriver en XML-fil som en Apache Spark-datakälla.
Krav
spark-xml
Skapa biblioteket som ett Maven-bibliotek. För Maven-koordinaten anger du:- Databricks Runtime 7.x och senare:
com.databricks:spark-xml_2.12:<release>
Se
spark-xml
Versioner för den senaste versionen av<release>
.- Databricks Runtime 7.x och senare:
Installera biblioteket i ett kluster.
Exempel
I exemplet i det här avsnittet används XML-filen böcker .
Hämta xml-filen för böcker:
$ wget https://github.com/databricks/spark-xml/raw/master/src/test/resources/books.xml
Ladda upp filen till DBFS.
Läsa och skriva XML-data
SQL
/*Infer schema*/
CREATE TABLE books
USING xml
OPTIONS (path "dbfs:/books.xml", rowTag "book")
/*Specify column names and types*/
CREATE TABLE books (author string, description string, genre string, _id string, price double, publish_date string, title string)
USING xml
OPTIONS (path "dbfs:/books.xml", rowTag "book")
Scala
// Infer schema
import com.databricks.spark.xml._ // Add the DataFrame.read.xml() method
val df = spark.read
.option("rowTag", "book")
.xml("dbfs:/books.xml")
val selectedData = df.select("author", "_id")
selectedData.write
.option("rootTag", "books")
.option("rowTag", "book")
.xml("dbfs:/newbooks.xml")
// Specify schema
import org.apache.spark.sql.types.{StructType, StructField, StringType, DoubleType}
val customSchema = StructType(Array(
StructField("_id", StringType, nullable = true),
StructField("author", StringType, nullable = true),
StructField("description", StringType, nullable = true),
StructField("genre", StringType, nullable = true),
StructField("price", DoubleType, nullable = true),
StructField("publish_date", StringType, nullable = true),
StructField("title", StringType, nullable = true)))
val df = spark.read
.option("rowTag", "book")
.schema(customSchema)
.xml("books.xml")
val selectedData = df.select("author", "_id")
selectedData.write
.option("rootTag", "books")
.option("rowTag", "book")
.xml("dbfs:/newbooks.xml")
R
# Infer schema
library(SparkR)
sparkR.session("local[4]", sparkPackages = c("com.databricks:spark-xml_2.12:<release>"))
df <- read.df("dbfs:/books.xml", source = "xml", rowTag = "book")
# Default `rootTag` and `rowTag`
write.df(df, "dbfs:/newbooks.xml", "xml")
# Specify schema
customSchema <- structType(
structField("_id", "string"),
structField("author", "string"),
structField("description", "string"),
structField("genre", "string"),
structField("price", "double"),
structField("publish_date", "string"),
structField("title", "string"))
df <- read.df("dbfs:/books.xml", source = "xml", schema = customSchema, rowTag = "book")
# In this case, `rootTag` is set to "ROWS" and `rowTag` is set to "ROW".
write.df(df, "dbfs:/newbooks.xml", "xml", "overwrite")
Alternativ
- Läsa
path
: Plats för XML-filer. Accepterar Standard Hadoop globbing uttryck.rowTag
: Radtaggen som ska behandlas som en rad. I den här XML-koden<books><book><book>...</books>
blirbook
till exempel värdet . Standard ärROW
.samplingRatio
: Samplingsförhållande för slutsatsdragningsschema (0,0 ~ 1). Standard är 1. Möjliga typer ärStructType
,ArrayType
,StringType
,LongType
,DoubleType
,BooleanType
TimestampType
ochNullType
, såvida du inte anger ett schema.excludeAttribute
: Om du vill exkludera attribut i element. Standardvärdet är falskt.nullValue
: Det värde som ska behandlas som ettnull
värde. Standard är""
.mode
: Läget för att hantera skadade poster. Standard ärPERMISSIVE
.PERMISSIVE
:- När den påträffar en skadad post anger du alla fält till
null
och placerar den felaktiga strängen i ett nytt fält som konfigurerats avcolumnNameOfCorruptRecord
. - När det stöter på ett fält med fel datatyp anger du det felande fältet till
null
.
- När den påträffar en skadad post anger du alla fält till
DROPMALFORMED
: ignorerar skadade poster.FAILFAST
: utlöser ett undantag när det identifierar skadade poster.
inferSchema
: omtrue
, försöker härleda en lämplig typ för varje resulterande DataFrame-kolumn, till exempel en boolesk, numerisk eller datumtyp. Omfalse
är alla resulterande kolumner av strängtyp. Standard ärtrue
.columnNameOfCorruptRecord
: Namnet på det nya fältet där felaktiga strängar lagras. Standard är_corrupt_record
.attributePrefix
: Prefixet för attribut så att attribut och element kan särskiljas. Det här är prefixet för fältnamn. Standard är_
.valueTag
: Taggen som används för värdet när det finns attribut i ett element som inte har några underordnade element. Standard är_VALUE
.charset
: StandardvärdetUTF-8
är men kan anges till andra giltiga teckenuppsättningsnamn.ignoreSurroundingSpaces
: Om blanksteg som omger värden ska hoppas över eller inte. Standardvärdet är falskt.rowValidationXSDPath
: Sökväg till en XSD-fil som används för att verifiera XML för varje rad. Rader som inte kan verifieras behandlas som parsningsfel som ovan. XSD påverkar inte det angivna eller härledda schemat. Om samma lokala sökväg inte redan visas på exekutorerna i klustret, bör XSD och andra som den är beroende av läggas till i Spark-kören med SparkContext.addFile. Om du i det här fallet vill använda lokal XSD/foo/bar.xsd
anroparaddFile("/foo/bar.xsd")
och skickar du"bar.xsd"
somrowValidationXSDPath
.
- Skriva
path
: Plats för att skriva filer.rowTag
: Radtaggen som ska behandlas som en rad. I den här XML-koden<books><book><book>...</books>
blirbook
till exempel värdet . Standard ärROW
.rootTag
: Rottaggen som ska behandlas som rot. I den här XML-koden<books><book><book>...</books>
blirbooks
till exempel värdet . Standard ärROWS
.nullValue
: Värdet för att skrivanull
värde. Standard är strängen"null"
. När"null"
skrivs inte attribut och element för fält.attributePrefix
: Prefixet för attribut för att särskilja attribut och element. Det här är prefixet för fältnamn. Standard är_
.valueTag
: Taggen som används för värdet när det finns attribut i ett element som inte har några underordnade element. Standard är_VALUE
.compression
: Komprimeringskodc som ska användas när du sparar till filen. Bör vara det fullständigt kvalificerade namnet på en klass som implementerarorg.apache.hadoop.io.compress.CompressionCodec
eller ett av skiftlägesokänsliga kortnamn (bzip2
,gzip
,lz4
ochsnappy
). Standardvärdet är ingen komprimering.
Stöder den förkortade namnanvändningen. Du kan använda xml
i stället för com.databricks.spark.xml
.
XSD-stöd
Du kan verifiera enskilda rader mot ett XSD-schema med hjälp av rowValidationXSDPath
.
Du använder verktyget com.databricks.spark.xml.util.XSDToSchema
för att extrahera ett Spark DataFrame-schema från vissa XSD-filer. Den stöder endast enkla, komplexa och sekvenstyper, endast grundläggande XSD-funktioner och är experimentella.
import com.databricks.spark.xml.util.XSDToSchema
import java.nio.file.Paths
val schema = XSDToSchema.read(Paths.get("/path/to/your.xsd"))
val df = spark.read.schema(schema)....xml(...)
Parsa kapslad XML
Även om den främst används för att konvertera en XML-fil till en DataFrame, kan du också använda from_xml
metoden för att parsa XML i en strängvärdeskolumn i en befintlig DataFrame och lägga till den som en ny kolumn med tolkade resultat som en struct med:
import com.databricks.spark.xml.functions.from_xml
import com.databricks.spark.xml.schema_of_xml
import spark.implicits._
val df = ... /// DataFrame with XML in column 'payload'
val payloadSchema = schema_of_xml(df.select("payload").as[String])
val parsed = df.withColumn("parsed", from_xml($"payload", payloadSchema))
Kommentar
mode
:- Om värdet är
PERMISSIVE
, standardvärdet, är parsningsläget i stället standardvärdetDROPMALFORMED
. Om du tar med en kolumn i schemat förfrom_xml
som matcharcolumnNameOfCorruptRecord
PERMISSIVE
utdataläget felaktiga poster till kolumnen i den resulterande structen. - Om värdet är inställt på
DROPMALFORMED
resulterar XML-värden som inte parsas korrekt i ettnull
värde för kolumnen. Inga rader tas bort.
- Om värdet är
from_xml
konverterar matriser med strängar som innehåller XML till matriser med parsade structs. Användschema_of_xml_array
i stället.from_xml_string
är ett alternativ för användning i UDF:er som körs på en sträng direkt i stället för en kolumn.
Konverteringsregler
På grund av strukturella skillnader mellan DataFrames och XML finns det vissa konverteringsregler från XML-data till DataFrame och från DataFrame till XML-data. Du kan inaktivera hanteringsattribut med alternativet excludeAttribute
.
Konvertera XML till DataFrame
Attribut: Attribut konverteras som fält med prefixet som anges i
attributePrefix
alternativet. OmattributePrefix
är_
, dokumentet<one myOneAttrib="AAAA"> <two>two</two> <three>three</three> </one>
skapar schemat:
root |-- _myOneAttrib: string (nullable = true) |-- two: string (nullable = true) |-- three: string (nullable = true)
Om ett element har attribut men inga underordnade element placeras attributvärdet i ett separat fält som anges i
valueTag
alternativet. OmvalueTag
är_VALUE
, dokumentet<one> <two myTwoAttrib="BBBBB">two</two> <three>three</three> </one>
skapar schemat:
root |-- two: struct (nullable = true) | |-- _VALUE: string (nullable = true) | |-- _myTwoAttrib: string (nullable = true) |-- three: string (nullable = true)
Konvertera DataFrame till XML
Skriva en XML-fil från DataFrame med ett fält ArrayType
med dess element, liksom ArrayType
ytterligare ett kapslat fält för elementet. Detta skulle inte inträffa vid läsning och skrivning av XML-data, utan när du skriver en DataFrame-läsning från andra källor. Därför har tur och retur i läsning och skrivning av XML-filer samma struktur, men att skriva en DataFrame-läsning från andra källor är möjligt att ha en annan struktur.
En dataram med schemat:
|-- a: array (nullable = true)
| |-- element: array (containsNull = true)
| | |-- element: string (containsNull = true)
och data:
+------------------------------------+
| a|
+------------------------------------+
|[WrappedArray(aa), WrappedArray(bb)]|
+------------------------------------+
skapar XML-filen:
<a>
<item>aa</item>
</a>
<a>
<item>bb</item>
</a>