Dela via


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

  1. 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>.

  2. Installera biblioteket i ett kluster.

Exempel

I exemplet i det här avsnittet används XML-filen böcker .

  1. Hämta xml-filen för böcker:

    $ wget https://github.com/databricks/spark-xml/raw/master/src/test/resources/books.xml
    
  2. 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>blir booktill exempel värdet . Standard är ROW.
    • samplingRatio: Samplingsförhållande för slutsatsdragningsschema (0,0 ~ 1). Standard är 1. Möjliga typer är StructType, ArrayType, StringType, LongType, DoubleType, BooleanTypeTimestampType och NullType, 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 ett null värde. Standard är "".
    • mode: Läget för att hantera skadade poster. Standard är PERMISSIVE.
      • 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 av columnNameOfCorruptRecord.
        • När det stöter på ett fält med fel datatyp anger du det felande fältet till null.
      • DROPMALFORMED: ignorerar skadade poster.
      • FAILFAST: utlöser ett undantag när det identifierar skadade poster.
    • inferSchema: om true, försöker härleda en lämplig typ för varje resulterande DataFrame-kolumn, till exempel en boolesk, numerisk eller datumtyp. Om falseär alla resulterande kolumner av strängtyp. Standard är true.
    • 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ärdet UTF-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.xsdanropar addFile("/foo/bar.xsd") och skickar du "bar.xsd" som rowValidationXSDPath.
  • 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>blir booktill exempel värdet . Standard är ROW.
    • rootTag: Rottaggen som ska behandlas som rot. I den här XML-koden <books><book><book>...</books>blir bookstill exempel värdet . Standard är ROWS.
    • nullValue: Värdet för att skriva null 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 implementerar org.apache.hadoop.io.compress.CompressionCodec eller ett av skiftlägesokänsliga kortnamn (bzip2, gzip, lz4och snappy). 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ärdet DROPMALFORMED. Om du tar med en kolumn i schemat för from_xml som matchar columnNameOfCorruptRecordPERMISSIVE utdataläget felaktiga poster till kolumnen i den resulterande structen.
    • Om värdet är inställt på DROPMALFORMEDresulterar XML-värden som inte parsas korrekt i ett null värde för kolumnen. Inga rader tas bort.
  • from_xml konverterar matriser med strängar som innehåller XML till matriser med parsade structs. Använd schema_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. Om attributePrefix ä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. Om valueTag ä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>