다음을 통해 공유


라이브러리를 사용하여 spark-xml XML 데이터 읽기 및 쓰기

Important

이 설명서는 사용 중지되었으며 업데이트되지 않을 수 있습니다. 콘텐츠에 멘션 제품, 서비스 또는 기술은 Databricks에서 공식적으로 승인되거나 테스트되지 않습니다.

네이티브 XML 파일 형식 지원은 공개 미리 보기로 사용할 수 있습니다. XML 파일 읽기 및 쓰기를 참조하세요.

이 문서에서는 XML 파일을 Apache Spark 데이터 원본으로 읽고 쓰는 방법을 설명합니다.

요구 사항

  1. spark-xml 라이브러리를 Maven 라이브러리로 만듭니다. Maven 좌표에 대해 다음을 지정합니다.

    • Databricks Runtime 7.x 이상: com.databricks:spark-xml_2.12:<release>

    <release>의 최신 버전은 spark-xml릴리스를 참조하세요.

  2. 클러스터에 라이브러리를 설치합니다.

예시

이 섹션의 예에서는 books XML 파일을 사용합니다.

  1. books XML 파일 검색:

    $ wget https://github.com/databricks/spark-xml/raw/master/src/test/resources/books.xml
    
  2. 파일을 DBFS에 업로드합니다.

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")

옵션

  • 읽기
    • path: XML 파일의 위치입니다. 표준 Hadoop 글로빙(globbing) 식을 허용합니다.
    • rowTag: 행으로 처리할 행 태그입니다. 예를 들어, 이 XML <books><book><book>...</books>에서 값은 book입니다. 기본값은 ROW입니다.
    • samplingRatio: 스키마 유추를 위한 샘플링 비율(0.0 ~ 1). 기본값은 1입니다. 스키마를 제공하지 않는 한 가능한 유형은 StructType, ArrayType, StringType, LongType, DoubleType, BooleanType, TimestampTypeNullType입니다.
    • excludeAttribute: 요소의 특성을 제외할지 여부입니다. 기본값은 false입니다.
    • nullValue: null 값으로 처리할 값입니다. 기본값은 ""입니다.
    • mode: 손상된 레코드를 처리하는 모드입니다. 기본값은 PERMISSIVE입니다.
      • PERMISSIVE:
        • 손상된 레코드를 발견하면 모든 필드를 null로 설정하고 잘못된 문자열을 columnNameOfCorruptRecord에 의해 구성된 새 필드에 넣습니다.
        • 잘못된 데이터 형식의 필드를 발견하면 문제가 되는 필드를 null로 설정합니다.
      • DROPMALFORMED: 손상된 레코드를 무시합니다.
      • FAILFAST: 손상된 레코드를 검색하면 예외가 throw됩니다.
    • inferSchema: true인 경우 부울, 숫자 또는 날짜 유형과 같은 각 결과 DataFrame 열에 대해 적절한 유형을 유추하려고 시도합니다. false인 경우 모든 결과 열은 문자열 유형입니다. 기본값은 true입니다.
    • columnNameOfCorruptRecord: 형식이 잘못된 문자열이 저장되는 새 필드의 이름입니다. 기본값은 _corrupt_record입니다.
    • attributePrefix: 특성과 요소를 구별하기 위한 특성 접두사. 이는 필드 이름의 접두사입니다. 기본값은 _입니다.
    • valueTag: 자식 요소가 없는 요소에 특성이 있을 때 값에 사용되는 태그입니다. 기본값은 _VALUE입니다.
    • charset: 기본값은 UTF-8이지만 다른 유효한 문자 집합 이름으로 설정할 수 있습니다.
    • ignoreSurroundingSpaces: 값 주변의 공백을 건너뛸지 여부입니다. 기본값은 false입니다.
    • rowValidationXSDPath: 각 행에 대한 XML의 유효성을 검사하는 데 사용되는 XSD 파일의 경로입니다. 유효성 검사에 실패한 행은 위와 같이 구문 분석 오류로 처리됩니다. XSD는 제공되거나 유추된 스키마에 달리 영향을 미치지 않습니다. 동일한 로컬 경로가 클러스터의 실행기에도 아직 표시되지 않는 경우 XSD 및 의존하는 다른 모든 경로를 SparkContext.addFile을 사용하여 Spark 실행기에 추가해야 합니다. 이 경우 로컬 XSD /foo/bar.xsd를 사용하려면 addFile("/foo/bar.xsd")를 호출하고 "bar.xsd"rowValidationXSDPath로 전달합니다.
  • 쓰기
    • path: 파일을 쓸 위치입니다.
    • rowTag: 행으로 처리할 행 태그입니다. 예를 들어, 이 XML <books><book><book>...</books>에서 값은 book입니다. 기본값은 ROW입니다.
    • rootTag: 루트로 취급할 루트 태그입니다. 예를 들어, 이 XML <books><book><book>...</books>에서 값은 books입니다. 기본값은 ROWS입니다.
    • nullValue: null 값을 쓸 값입니다. 기본값은 "null" 문자열입니다. "null"인 경우 필드의 특성 및 요소를 쓰지 않습니다.
    • attributePrefix: 특성과 요소를 구별하기 위한 특성의 접두사. 이는 필드 이름의 접두사입니다. 기본값은 _입니다.
    • valueTag: 자식 요소가 없는 요소에 특성이 있을 때 값에 사용되는 태그입니다. 기본값은 _VALUE입니다.
    • compression: 파일에 저장할 때 사용할 압축 코덱입니다. org.apache.hadoop.io.compress.CompressionCodec을 구현하는 클래스의 정규화된 이름이거나 대/소문자를 구분하지 않는 짧은 이름(bzip2, gzip, lz4snappy) 중 하나여야 합니다. 기본값은 압축 안 함으로 설정되어 있습니다.

단축 이름 사용을 지원합니다. com.databricks.spark.xml 대신 xml을 사용할 수 있습니다.

XSD 지원

rowValidationXSDPath를 사용하여 XSD 스키마에 대해 개별 행의 유효성을 검사할 수 있습니다.

com.databricks.spark.xml.util.XSDToSchema 유틸리티를 사용하여 일부 XSD 파일에서 Spark DataFrame 스키마를 추출합니다. 단순, 복합 및 시퀀스 유형만 지원하며 기본 XSD 기능만 지원하며 실험적입니다.

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(...)

중첩된 XML 구문 분석

주로 XML 파일을 DataFrame으로 변환하는 데 사용되지만 from_xml 메서드를 사용하여 기존 DataFrame의 문자열 값 열에서 XML을 구문 분석하고 구문 분석된 결과가 있는 새 열로 추가할 수도 있습니다.

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))

참고 항목

  • mode:
    • 기본값인 PERMISSIVE로 설정하면 구문 분석 모드가 대신 기본값이 DROPMALFORMED로 설정됩니다. columnNameOfCorruptRecord와 일치하는 from_xml의 스키마에 열을 포함하는 경우 PERMISSIVE 모드는 결과 구조체의 해당 열에 형식이 잘못된 레코드를 출력합니다.
    • DROPMALFORMED로 설정하면 올바르게 구문 분석되지 않는 XML 값으로 인해 열에 대해 null 값이 생성됩니다. 행이 삭제되지 않습니다.
  • from_xml은 XML을 포함하는 문자열 배열을 구문 분석된 구조체 배열로 변환합니다. 대신 schema_of_xml_array을 사용합니다.
  • from_xml_string은 열 대신 문자열에서 직접 작동하는 UDF에서 사용하기 위한 대안입니다.

변환 규칙

DataFrame과 XML의 구조적 차이로 인해 XML 데이터에서 DataFrame으로, DataFrame에서 XML 데이터로의 변환 규칙이 있습니다. excludeAttribute 옵션을 사용하여 특성 처리를 사용하지 않도록 설정할 수 있습니다.

XML을 DataFrame으로 변환

  • 특성: 특성은 attributePrefix 옵션에 지정된 접두사가 있는 필드로 변환됩니다. attributePrefix_이면 문서

    <one myOneAttrib="AAAA">
        <two>two</two>
        <three>three</three>
    </one>
    

    스키마를 생성합니다.

    root
    |-- _myOneAttrib: string (nullable = true)
    |-- two: string (nullable = true)
    |-- three: string (nullable = true)
    
  • 요소에 특성이 있지만 자식 요소가 없는 경우 특성 값은 valueTag 옵션에 지정된 별도의 필드에 배치됩니다. valueTag_VALUE이면 문서

    <one>
        <two myTwoAttrib="BBBBB">two</two>
        <three>three</three>
    </one>
    

    스키마를 생성합니다.

    root
    |-- two: struct (nullable = true)
    |    |-- _VALUE: string (nullable = true)
    |    |-- _myTwoAttrib: string (nullable = true)
    |-- three: string (nullable = true)
    

DataFrame을 XML로 변환

요소에 대한 추가 중첩 필드가 있는 것처럼 ArrayType 해당 요소가 있는 필드 ArrayType 가 있는 DataFrame에서 XML 파일을 작성합니다. 이는 XML 데이터를 읽고 쓰는 것이 아니라 다른 원본에서 읽은 DataFrame을 작성하는 경우에 발생합니다. 따라서 XML 파일을 읽고 쓸 때의 왕복은 구조는 같지만 다른 원본에서 읽은 DataFrame을 쓰는 것은 다른 구조를 가질 수 있습니다.

스키마가 있는 DataFrame:

 |-- a: array (nullable = true)
 |    |-- element: array (containsNull = true)
 |    |    |-- element: string (containsNull = true)

및 데이터:

+------------------------------------+
|                                   a|
+------------------------------------+
|[WrappedArray(aa), WrappedArray(bb)]|
+------------------------------------+

XML 파일을 생성합니다.

<a>
  <item>aa</item>
</a>
<a>
  <item>bb</item>
</a>