Lire et écrire des données XML à l’aide de la bibliothèque spark-xml
Important
Cette documentation a été mise hors service et peut ne pas être mise à jour. Les produits, services ou technologies mentionnés dans ce contenu ne sont pas officiellement approuvés ou testés par Databricks.
La prise en charge native du format de fichier XML est disponible en préversion publique. Consultez Lire et écrire des fichiers XML.
Cet article explique comment lire et écrire un fichier XML en tant que Apache Spark source de données.
Spécifications
Créez la
spark-xml
bibliothèque en tant que bibliothèque Maven. Pour la coordonnée Maven, spécifiez :- Databricks Runtime 7.x et ultérieur :
com.databricks:spark-xml_2.12:<release>
Consultez
spark-xml
Versions pour connaître la dernière version de<release>
.- Databricks Runtime 7.x et ultérieur :
Installer la bibliothèque sur un cluster.
Exemple
L’exemple de cette section utilise le fichier XML books .
Récupérez le fichier de documentation XML :
$ wget https://github.com/databricks/spark-xml/raw/master/src/test/resources/books.xml
Télécharger le fichier à DBFS.
Lire et écrire des données XML
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")
Options
- Lire
path
: Emplacement des fichiers XML. Accepte les expressions globbing Hadoop standard.rowTag
: Balise de ligne à traiter en tant que ligne. Par exemple, dans ce code XML<books><book><book>...</books>
, la valeur estbook
. La valeur par défaut estROW
.samplingRatio
: Taux d’échantillonnage pour la déduction du schéma (0,0 ~ 1). 1 constitue la valeur par défaut. Les types possibles sontStructType
,ArrayType
,StringType
,LongType
,DoubleType
,BooleanType
,TimestampType
etNullType
, sauf si vous fournissez un schéma.excludeAttribute
: Indique s’il faut exclure des attributs dans les éléments. La valeur par défaut est false.nullValue
: Valeur à traiter en tant que valeurnull
. La valeur par défaut est""
.mode
: Mode de traitement des enregistrements endommagés. La valeur par défaut estPERMISSIVE
.PERMISSIVE
:- Lorsqu’il rencontre un enregistrement endommagé, affecte à
null
tous les champs la valeur et place la chaîne incorrecte dans un nouveau champ configuré parcolumnNameOfCorruptRecord
. - Lorsqu’il rencontre un champ de type de données incorrect, définit le champ incriminé sur
null
.
- Lorsqu’il rencontre un enregistrement endommagé, affecte à
DROPMALFORMED
: ignore les enregistrements endommagés.FAILFAST
: lève une exception en présence d’enregistrements endommagés.
inferSchema
: sitrue
, tente de déduire un type approprié pour chaque colonne tableau résultante, comme un type booléen, numérique ou de date. Sifalse
la valeur est, toutes les colonnes résultantes sont de type chaîne. La valeur par défaut esttrue
.columnNameOfCorruptRecord
: Nom du nouveau champ dans lequel sont stockées les chaînes mal formées. La valeur par défaut est_corrupt_record
.attributePrefix
: Préfixe des attributs afin de différencier les attributs et les éléments. Il s’agit du préfixe pour les noms de champs. La valeur par défaut est_
.valueTag
: Balise utilisée pour la valeur lorsqu’il existe des attributs dans un élément qui n’a pas d’éléments enfants. La valeur par défaut est_VALUE
.charset
: Par défautUTF-8
, mais peut être défini sur d’autres noms de jeux de caractères valides.ignoreSurroundingSpaces
: Indique si les espaces blancs qui entourent les valeurs doivent être ignorés. La valeur par défaut est false.rowValidationXSDPath
: Chemin d’accès à un fichier XSD utilisé pour valider le code XML de chaque ligne. Les lignes qui ne peuvent pas être validées sont traitées comme des erreurs d’analyse comme indiqué ci-dessus. Le XSD n’affecte pas le schéma fourni ou inféré. Si le même chemin d’accès local n’est pas déjà également visible sur les exécuteurs du cluster, le schéma XSD et les autres éléments dont il dépend doivent être ajoutés aux exécuteurs Spark avec SparkContext.addFile. Dans ce cas, pour utiliser le XSD local/foo/bar.xsd
, appelezaddFile("/foo/bar.xsd")
et transmettez"bar.xsd"
en tant querowValidationXSDPath
.
- Write
path
: Emplacement d’écriture des fichiers.rowTag
: Balise de ligne à traiter en tant que ligne. Par exemple, dans ce code XML<books><book><book>...</books>
, la valeur estbook
. La valeur par défaut estROW
.rootTag
: Balise racine à traiter comme racine. Par exemple, dans ce code XML<books><book><book>...</books>
, la valeur estbooks
. La valeur par défaut estROWS
.nullValue
: Valeur à écrirenull
valeur. La valeur par défaut est la chaîne"null"
. Quand"null"
est présent, il n’écrit pas les attributs et les éléments des champs.attributePrefix
: Le préfixe des attributs pour différencier les attributs des éléments. Il s’agit du préfixe pour les noms de champs. La valeur par défaut est_
.valueTag
: Balise utilisée pour la valeur lorsqu’il existe des attributs dans un élément qui n’a pas d’éléments enfants. La valeur par défaut est_VALUE
.compression
: Codec de compression à utiliser lors de l’enregistrement dans le fichier. Doit être le nom qualifié complet d’une classe qui implémenteorg.apache.hadoop.io.compress.CompressionCodec
ou un des noms courts ne respectant pas la casse (bzip2
,gzip
,lz4
etsnappy
). La valeur par défaut est aucune compression.
Prend en charge l’utilisation raccourcie des noms ; Vous pouvez utiliser xml
à la place de com.databricks.spark.xml
.
Prise en charge XSD
Vous pouvez valider des lignes individuelles par rapport à un schéma XSD à l’aide de rowValidationXSDPath
.
Vous utilisez l’utilitaire com.databricks.spark.xml.util.XSDToSchema
pour extraire un schéma Spark tableau à partir de fichiers XSD. Il prend uniquement en charge les types simples, complexes et de séquence, uniquement les fonctionnalités XSD de base et est expérimental.
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(...)
Analyser les données XML imbriquées
Bien qu’il soit principalement utilisé pour convertir un fichier XML en tableau, vous pouvez également utiliser la méthode from_xml
pour analyser du code XML dans une colonne à valeur de chaîne d’un tableau existant et l'ajouter en tant que nouvelle colonne avec des résultats analysés en tant que struct avec :
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))
Remarque
mode
:- Si la valeur
PERMISSIVE
est, la valeur par défaut est le mode d’analyse à la place par défaut estDROPMALFORMED
. Si vous incluez une colonne dans le schéma pour qui correspond à,from_xml
lecolumnNameOfCorruptRecord
mode génère desPERMISSIVE
enregistrements incorrects dans cette colonne du struct résultant. - Si la valeur est
DROPMALFORMED
, les valeurs XML qui n’analysent pas correctement entraînent une valeurnull
pour la colonne. Aucune ligne n’est supprimée.
- Si la valeur
from_xml
convertit des tableaux de chaînes contenant du code XML en tableaux de structs analysés. Utilisezschema_of_xml_array
à la place.from_xml_string
est une alternative à utiliser dans les fonctions définies par l’utilisateur qui s’exécutent directement sur une chaîne au lieu d’une colonne.
Règles de conversion
En raison des différences structurelles entre trames et XML, il existe des règles de conversion des données XML vers tableau et de tableau vers les données XML. Vous pouvez désactiver la gestion des attributs avec l’option excludeAttribute
.
Convertir XML en tableau
Attributs : les attributs sont convertis en champs avec le préfixe spécifié dans l'option
attributePrefix
. SiattributePrefix
est_
, le document<one myOneAttrib="AAAA"> <two>two</two> <three>three</three> </one>
produit le schéma :
root |-- _myOneAttrib: string (nullable = true) |-- two: string (nullable = true) |-- three: string (nullable = true)
Si un élément possède des attributs mais pas d’éléments enfants, la valeur de l’attribut est placée dans un champ séparé spécifié dans l'option
valueTag
. SivalueTag
est_VALUE
, le document<one> <two myTwoAttrib="BBBBB">two</two> <three>three</three> </one>
produit le schéma :
root |-- two: struct (nullable = true) | |-- _VALUE: string (nullable = true) | |-- _myTwoAttrib: string (nullable = true) |-- three: string (nullable = true)
Convertir tableau en XML
L’écriture d’un fichier XML à partir d’un DataFrame, ayant un champ ArrayType
avec son élément comme ArrayType
, aurait un champ imbriqué supplémentaire pour l’élément. Cela ne se produit pas lors de la lecture et de l’écriture de données XML, mais l’écriture d’un DataFrame est lue à partir d’autres sources. Par conséquent, l’aller-retour dans la lecture et l’écriture des fichiers XML a la même structure, mais l’écriture d’une tableau lue à partir d’autres sources peut avoir une structure différente.
Un tableau avec le schéma :
|-- a: array (nullable = true)
| |-- element: array (containsNull = true)
| | |-- element: string (containsNull = true)
et des données :
+------------------------------------+
| a|
+------------------------------------+
|[WrappedArray(aa), WrappedArray(bb)]|
+------------------------------------+
produit le fichier XML :
<a>
<item>aa</item>
</a>
<a>
<item>bb</item>
</a>