【问题标题】:How do I transform a List<String[]> to an XML Object using XMLMapper (Jackson)?如何使用 XMLMapper (Jackson) 将 List<String[]> 转换为 XML 对象?
【发布时间】:2019-06-24 07:45:20
【问题描述】:

我有一个表示为List&lt;String[]&gt; 的表。列表的第一个元素是标题,其他元素是一行。我不提前知道 List 的结构,所以创建一个包含属性/字段的类不是一个选项。

假设我有一个如下所示的表(我们称之为“数据库”):

Age|Name|Sex
23 |John|Male
19 |Sam |Female
18 |Alex|Male

列表的第一个元素是一个字符串数组,如下所示: ["Age", "Name", Sex"] 而行看起来像这样 ["23", "John", "Male"]

如何获得如下所示的 XML 输出:

<Table name="Database">
<Row name="1">
    <Item name="Age">23</Item>
    <Item name="Name">John</Item>
    <Item name="Sex">Male</Item>
</Row>
<Row name="2">
    <Item name="Age">19</Item>
    <Item name="Name">Sam</Item>
    <Item name="Sex">Female</Item>
</Row>
<Row name="3">
    <Item name="Age">18</Item>
    <Item name="Name">Alex</Item>
    <Item name="Sex">Male</Item>
</Row>

基本上,我收到了一个表格的输入,我运行我的算法并得到一个列表作为返回,第一个元素是标题。我尝试过使用 XMLMapper,它可以快速将其映射到 XML,但我没有得到我想要的格式/结构。

public String createXMLObject() throws IOException {
List<String[]> table = extractData(); //extractData() is my custom method 
ObjectMapper mapper = new XmlMapper();
String result = mapper.writeValueAsString(table);
mapper.writeValue(new File("test.xml"), table);
System.out.println(result);
return result;
}

【问题讨论】:

  • 您确定要每个XML Node 命名为Node 吗?不是&lt;table&gt;&lt;item&gt;&lt;age&gt;18&lt;/age&gt;....&lt;/item&gt;&lt;/table&gt;
  • @MichałZiober 当然,项目对我来说很好用。它会更新它。
  • 创建类TableRowItem,然后将List&lt;String[]&gt;转换为对象,最后将Table对象转换为XML。 ObjectMapper 的目的是转换 objects,因此您必须首先创建与您要生成的 XML 匹配的对象。

标签: java xml jackson


【解决方案1】:

不需要 Jackson 的开销,尤其是因为无论如何您都必须先将数据转换为不同的格式。

只需使用 StAX,如下所示:

List<String[]> table = Arrays.asList(
        new String[] { "Age", "Name", "Sex"    },
        new String[] { "23" , "John", "Male"   },
        new String[] { "19" , "Sam" , "Female" },
        new String[] { "18" , "Alex", "Male"   } );

XMLStreamWriter xml = XMLOutputFactory.newFactory().createXMLStreamWriter(System.out);
xml.writeStartElement("Table");
xml.writeAttribute("name", "Database");

String[] header = table.get(0);
for (int rowNo = 1; rowNo < table.size(); rowNo++) {
    String[] row = table.get(rowNo);
    xml.writeCharacters(System.lineSeparator());
    xml.writeStartElement("Row");
    xml.writeAttribute("name", String.valueOf(rowNo));
    for (int colIdx = 0; colIdx < header.length; colIdx++) {
        xml.writeCharacters(System.lineSeparator() + "    ");
        xml.writeStartElement("Item");
        xml.writeAttribute("name", header[colIdx]);
        xml.writeCharacters(row[colIdx]);
        xml.writeEndElement(); // </Item>
    }
    xml.writeCharacters(System.lineSeparator());
    xml.writeEndElement(); // </Row>
}

xml.writeCharacters(System.lineSeparator());
xml.writeEndElement(); // </Table>
xml.close();

输出

<Table name="Database">
<Row name="1">
    <Item name="Age">23</Item>
    <Item name="Name">John</Item>
    <Item name="Sex">Male</Item>
</Row>
<Row name="2">
    <Item name="Age">19</Item>
    <Item name="Name">Sam</Item>
    <Item name="Sex">Female</Item>
</Row>
<Row name="3">
    <Item name="Age">18</Item>
    <Item name="Name">Alex</Item>
    <Item name="Sex">Male</Item>
</Row>
</Table>

【讨论】:

  • 我会试试看它是否有效,但我认为你的解决方案是最好的。
  • 是的,这种自定义看起来不错,否则我会推荐 documentBuilder 类型的解决方案,基本上是自己设置所有值。
  • @Andreas 只有一件事:当我使用 IndentingXMLStreamWriter 时,强制换行符效果不佳。只是提醒任何想知道为什么他们会得到像“ ”这样奇怪的字符的人如果他们尝试将此 xml 字符串漂亮地打印到文件中,则在每个标签的末尾。
  • @rosenjcb com.sun.xml.txw2.output.IndentingXMLStreamWriter 是一个您应该使用的内部类。 --- 当然,如果您使用的是为您缩进和换行的编写器,您不应该自己插入行分隔符和缩进空格!
  • @Andreas Huh 一个糟糕的 Stack Overflow 答案建议使用它我认为......或者它可能是另一个站点。
【解决方案2】:

使用地图

List<String> head = Arrays.asList(data.get(0));
List<Map<String,String>> output = new ArrayList<>();
for (int i = 1; i < data.size(); i++) {
    String[] element = data.get(i);
    Map<String,String> person = new HashMap<>();
    for (int j = 0; j < element.length; j++) {
        person.put(head.get(j),element[j]);
    }
    output.add(person);
}

输出是

<ArrayList>
   <item>
      <Sex>Male</Sex>
      <Age>23</Age>
      <Name>John</Name>
   </item>
   <item>
      <Sex>Female</Sex>
      <Age>19</Age>
      <Name>Sam</Name>
   </item>
   <item>
      <Sex>Male</Sex>
      <Age>18</Age>
      <Name>Alex</Name>
   </item>
</ArrayList>

【讨论】:

  • 这不是问题所要求的 XML。
  • @Andreas 是对的,但我确实喜欢它。我实际上使用了一个类似的使用地图的解决方案。
  • @mavriksc 您应该使用 LinkedHashMap 来保留项目的顺序。
  • 我主要是在回答分解成动态结构而不是预定义对象的部分问题。仍然需要进行一些工作以将其序列化为所需的确切格式。
猜你喜欢
  • 2020-03-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-27
  • 2013-08-26
  • 2012-09-28
  • 1970-01-01
  • 2020-01-11
相关资源
最近更新 更多