如何从中解析 XML 到 return 一个 Map?
How to parse XML to return a Map from it?
我想解析如下所示的 XML:
<ROOT>
<ECHO>
<column1>NAME</column1>
<column2>LN</column2>
<column3>CD</column3>
<column4>DATA0</column4>
<column5>DATA1</column5>
<column6>DATA2</column6>
<column7>DATA3</column7>
</ECHO>
<ECHO1>
<column1>NAME</column1>
<column2>LN</column2>
<column3>CD</column3>
<column4>DATA0</column4>
</ECHO1>
</ROOT>
这里我想要一个 Map
被返回并且不知何故密钥应该是并且相对于所有其他 children 应该存储在列表中
准确来说应该是这样的 <key=echo ,List=ln ,cd,data0,data1,data2,data3>
.
我尝试探索 JAXB,但我认为这对我的情况没有帮助,因为 children 的名称在每种情况下都不相同,所以我无法在任何模型中定义静态字段数并解组 XML 建模。我想尽量减少编码工作,因此 SAX 和 DOM 解析器永远不会出现在我的雷达上。任何人都可以在没有太多编码的情况下提供任何线索吗?
I want to minimize the coding effort so SAX and DOM parser is never on my radar.
我认为您需要重新校准雷达 :-) 我怀疑 SAX 或 DOM 或类似的方法是最简单的方法。
XML 绑定依赖于某种 XML 模式来提供牵引力。您的 XML.
似乎无法使用架构
对于它的价值,您可以在 50 到 100 行 Java 代码中为此用例编写一个基于 DOM 的提取器。这不是一项巨大的编码工作,而且可能比在互联网上搜索替代品要省力。
虽然我确实认为这个问题有点奇怪,并且我同意以可以使用 SAX 或 DOM 的方式重新考虑问题可能是明智的,但您可以使用一个简单的XmlPullParser 来完成这个。
假设您的 XML 始终根据您的示例构建 w.r.t 键、值等的深度,并假设您想要的输出是 Map<String, List<String>>
,您可能能够做类似的事情:
int eventType;
String key = null;
List<String> value = null;
HashMap<String, List<String>> map = new HashMap<String, List<String>>();
while ((eventType = xpp.getEventType()) != XmlPullParser.END_DOCUMENT) {
switch (eventType) {
case XmlPullParser.START_TAG:
if (xpp.getDepth() == 2) {
key = xpp.getName();
value = new ArrayList<String>();
}
break;
case XmlPullParser.TEXT:
if (xpp.getDepth() == 3) {
value.add(xpp.getText());
}
break;
case XmlPullParser.END_TAG:
if (xpp.getDepth() == 2) {
map.put(key, value);
}
break;
}
}
Beggs 基本上是问你对XML格式有没有控制权,也就是能不能稍微修改一下?你还没有回答这个问题。
假设可以。以下是您的原始 XML 的略微修改版本:
<ROOT>
<data name="ECHO">
<column>NAME</column>
<column>LN</column>
<column>CD</column>
<column>DATA0</column>
<column>DATA1</column>
<column>DATA2</column>
<column>DATA3</column>
</data>
<data name="ECHO1">
<column>NAME</column>
<column>LN</column>
<column>CD</column>
<column>DATA0</column>
</data>
</ROOT>
这可以很容易地用 JAXB 解析。为文档的根创建一个class,我将其命名为Root
。为数据元素创建一个class,我将其命名为Data
。
Class根目录:
import java.util.List;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name="ROOT")
public class Root {
@XmlElement
public List<Data> data;
}
Class数据:
import java.util.List;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
public class Data {
@XmlAttribute
public String name;
@XmlElement
public List<String> column;
}
然后是一个 class,其主要功能将从当前目录中名为 test.xml
的文件加载 XML 文件。然后数据将传输到 Map
并打印地图以显示其内容。
import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
public class Test {
public static void main(String[] args) throws Exception {
JAXBContext ctx = JAXBContext.newInstance(Root.class);
Unmarshaller um = ctx.createUnmarshaller();
Root root = (Root) um.unmarshal(new File("test.xml"));
// XML is now loaded. Turn it into a Map
Map<String,List<String>> map = new HashMap<String, List<String>>();
for (Data data : root.data) {
map.put(data.name, data.column);
}
System.out.println(map); // Easily show content
}
}
如果您无法控制 XML 数据的格式,此解决方案将不起作用。
我想解析如下所示的 XML:
<ROOT>
<ECHO>
<column1>NAME</column1>
<column2>LN</column2>
<column3>CD</column3>
<column4>DATA0</column4>
<column5>DATA1</column5>
<column6>DATA2</column6>
<column7>DATA3</column7>
</ECHO>
<ECHO1>
<column1>NAME</column1>
<column2>LN</column2>
<column3>CD</column3>
<column4>DATA0</column4>
</ECHO1>
</ROOT>
这里我想要一个 Map
被返回并且不知何故密钥应该是并且相对于所有其他 children 应该存储在列表中
准确来说应该是这样的 <key=echo ,List=ln ,cd,data0,data1,data2,data3>
.
我尝试探索 JAXB,但我认为这对我的情况没有帮助,因为 children 的名称在每种情况下都不相同,所以我无法在任何模型中定义静态字段数并解组 XML 建模。我想尽量减少编码工作,因此 SAX 和 DOM 解析器永远不会出现在我的雷达上。任何人都可以在没有太多编码的情况下提供任何线索吗?
I want to minimize the coding effort so SAX and DOM parser is never on my radar.
我认为您需要重新校准雷达 :-) 我怀疑 SAX 或 DOM 或类似的方法是最简单的方法。
XML 绑定依赖于某种 XML 模式来提供牵引力。您的 XML.
似乎无法使用架构对于它的价值,您可以在 50 到 100 行 Java 代码中为此用例编写一个基于 DOM 的提取器。这不是一项巨大的编码工作,而且可能比在互联网上搜索替代品要省力。
虽然我确实认为这个问题有点奇怪,并且我同意以可以使用 SAX 或 DOM 的方式重新考虑问题可能是明智的,但您可以使用一个简单的XmlPullParser 来完成这个。
假设您的 XML 始终根据您的示例构建 w.r.t 键、值等的深度,并假设您想要的输出是 Map<String, List<String>>
,您可能能够做类似的事情:
int eventType;
String key = null;
List<String> value = null;
HashMap<String, List<String>> map = new HashMap<String, List<String>>();
while ((eventType = xpp.getEventType()) != XmlPullParser.END_DOCUMENT) {
switch (eventType) {
case XmlPullParser.START_TAG:
if (xpp.getDepth() == 2) {
key = xpp.getName();
value = new ArrayList<String>();
}
break;
case XmlPullParser.TEXT:
if (xpp.getDepth() == 3) {
value.add(xpp.getText());
}
break;
case XmlPullParser.END_TAG:
if (xpp.getDepth() == 2) {
map.put(key, value);
}
break;
}
}
Beggs 基本上是问你对XML格式有没有控制权,也就是能不能稍微修改一下?你还没有回答这个问题。
假设可以。以下是您的原始 XML 的略微修改版本:
<ROOT>
<data name="ECHO">
<column>NAME</column>
<column>LN</column>
<column>CD</column>
<column>DATA0</column>
<column>DATA1</column>
<column>DATA2</column>
<column>DATA3</column>
</data>
<data name="ECHO1">
<column>NAME</column>
<column>LN</column>
<column>CD</column>
<column>DATA0</column>
</data>
</ROOT>
这可以很容易地用 JAXB 解析。为文档的根创建一个class,我将其命名为Root
。为数据元素创建一个class,我将其命名为Data
。
Class根目录:
import java.util.List;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name="ROOT")
public class Root {
@XmlElement
public List<Data> data;
}
Class数据:
import java.util.List;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
public class Data {
@XmlAttribute
public String name;
@XmlElement
public List<String> column;
}
然后是一个 class,其主要功能将从当前目录中名为 test.xml
的文件加载 XML 文件。然后数据将传输到 Map
并打印地图以显示其内容。
import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
public class Test {
public static void main(String[] args) throws Exception {
JAXBContext ctx = JAXBContext.newInstance(Root.class);
Unmarshaller um = ctx.createUnmarshaller();
Root root = (Root) um.unmarshal(new File("test.xml"));
// XML is now loaded. Turn it into a Map
Map<String,List<String>> map = new HashMap<String, List<String>>();
for (Data data : root.data) {
map.put(data.name, data.column);
}
System.out.println(map); // Easily show content
}
}
如果您无法控制 XML 数据的格式,此解决方案将不起作用。