Пользовательская схема с вложенным родительским узлом в spark-xml

Я новичок в spark-xml, и мне сложно подготовить пользовательскую схему для моего объекта. Прошу вас всех помочь мне. Ниже то, что я пробовал.

Я использую Spark 1.4.7 и spark-xml версии 0.3.5.

Тест.Java

StructType customSchema = new StructType(new StructField[]{
    new StructField("id", DataTypes.StringType, true, Metadata.empty()),
    new StructField("name", DataTypes.StringType, true, Metadata.empty()),

    DataTypes.createStructField("names", DataTypes.createStructType(new StructField[]{
        DataTypes.createStructField("test", DataTypes.createArrayType(DataTypes.StringType),
            true)}), true)
});

final JavaRDD<Row> map = spoofRDD()
    .map(book -> RowFactory.create(
        book.getId(),
        book.getName(),
        book.getNames()));

final DataFrame df = sqlContext.createDataFrame(map, customSchema);
df.show();
df.printSchema();



private JavaRDD<Book> spoofRDD() {

Book book1 = Book.builder().id("1").name("Name1")
    .names(new String[]{"1", "2"}).build();
List<Book> books = new ArrayList<>();
books.add(book1);

return javaSparkContext.parallelize(books);
}

Мой класс POJO Book.Java

private final String id;
private final String name;
private final String[] names;

Мой ожидаемый XML

<books>
<book>
    <id>1</id>
    <name>Name1</name>
    **<parent>**
        <names>1</names>
        <names>2</names>
    **</parent>**
</book>
<book>
    <id>2</id>
    <name>Name2</name>
    **<parent>**
        <names>1</names>
        <names>2</names>
    **</parent>**
</book>

So, as you see I wish to have a nested tag in the parent. How can I modify my customSchema to achieve the same.


person Punith Raj    schedule 27.03.2018    source источник


Ответы (1)


Правильная схема для желаемого вывода XML:

root
 |-- id: long (nullable = true)
 |-- name: string (nullable = true)
 |-- parent: struct (nullable = true)
 |    |-- names: array (nullable = true)
 |    |    |-- element: long (containsNull = true)]

в то время как ваша текущая схема:

root
 |-- id: string (nullable = true)
 |-- name: string (nullable = true)
 |-- names: struct (nullable = true)
 |    |-- test: array (nullable = true)
 |    |    |-- element: string (containsNull = true)

Таким образом, единственное, что вам нужно изменить здесь, это имя тега с test на name и с names на parent и тип значения для содержимого массива.

new StructType(new StructField[]{
  new StructField("id", DataTypes.StringType, true, Metadata.empty()),
  new StructField("name", DataTypes.StringType, true, Metadata.empty()),

  DataTypes.createStructField("names", DataTypes.createStructType(new StructField[]{
    DataTypes.createStructField("test", DataTypes.createArrayType(DataTypes.StringType),
        true)}), true)
})

Настоящая проблема — это данные. Поскольку parent должно быть struct, вывод getNames должен быть заключен в Row:

.map(book -> RowFactory.create(
    book.getId(),
    book.getName(),
    RowFactory.create(book.getNames())));
person Alper t. Turker    schedule 10.04.2018