Java 将简单的XML行优雅地转换为地图

Java 将简单的XML行优雅地转换为地图,java,xml,Java,Xml,我正在Java中使用stackoverflow数据集进行一些工作,并使用如下字符串: <row Id="1" PostId="35314" Score="8" Text="not sure why this is getting downvoted -- it is correct! Double check it in your compiler if you don't believe him!" CreationDate="2008-09-06T08:07:10

我正在Java中使用stackoverflow数据集进行一些工作,并使用如下字符串:

 <row Id="1" PostId="35314" Score="8" Text="not sure why this is getting
     downvoted -- it is correct! Double check it in your compiler if you
     don't believe him!" CreationDate="2008-09-06T08:07:10.730" UserId="1" />

(为了可读性增加了换行符)

假设上面的数据是一个字符串,那么将其转换为
地图
的最优雅的方式是什么,键是标签(
“Id”
“Score”
,…),值是包含值的字符串(
“1”
“35314”
,…)?我想优雅、易读、简洁地完成这项工作,因为很多人都会看到这段代码。我写了一篇文章,里面有各种各样的字符串操作,真是难看


在我使用的框架中,我必须一次处理一行,因此我不能一次解析整个XML结构(所有行)。我一次只能做一行。

您可以使用SAX解析器来完成这项工作。它会根据您的需求逐行处理XML。

您可以使用SAX解析器来实现这一点。它根据您的要求逐行处理XML。

请参阅线程以获得可能的解决方案。

请参阅线程以获得可能的解决方案。

公共静态映射转换XMLTOMAP(字符串XML){
public static Map<String, String> transformXmlToMap(String xml) {
    Document doc = null;
    try {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        factory.setNamespaceAware(false);
        DocumentBuilder bldr = factory
                .newDocumentBuilder();

        doc = bldr.parse(new ByteArrayInputStream(xml.getBytes()));
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    }

    Map<String, String> map = new HashMap<String, String>();
    NamedNodeMap attributeMap = doc.getDocumentElement().getAttributes();

    for (int i = 0; i < attributeMap.getLength(); ++i) {
        Attr n = (Attr) attributeMap.item(i);

        map.put(n.getName(), n.getValue());
    }

    return map;
}
单据单据=空; 试一试{ DocumentBuilderFactory工厂=DocumentBuilderFactory.newInstance(); factory.setNamespaceAware(false); DocumentBuilder bldr=工厂 .newDocumentBuilder(); doc=bldr.parse(新的ByteArrayInputStream(xml.getBytes()); }捕获(例外e){ e、 printStackTrace(); 返回null; } Map Map=newhashmap(); NamedNodeMap attributeMap=doc.getDocumentElement().getAttributes(); 对于(int i=0;i
这将使用org.w3c.*库进行处理。它不像简单的字符串处理方法那么轻量级,所以希望有人能想出更好的方法。将DocumentBuilder存储为静态最终变量将有助于加快处理速度,因为您不需要每次都创建一个{ 单据单据=空; 试一试{ DocumentBuilderFactory工厂=DocumentBuilderFactory.newInstance(); factory.setNamespaceAware(false); DocumentBuilder bldr=工厂 .newDocumentBuilder(); doc=bldr.parse(新的ByteArrayInputStream(xml.getBytes()); }捕获(例外e){ e、 printStackTrace(); 返回null; } Map Map=newhashmap(); NamedNodeMap attributeMap=doc.getDocumentElement().getAttributes(); 对于(int i=0;i

这将使用org.w3c.*库进行处理。它不像简单的字符串处理方法那么轻量级,所以希望有人能想出更好的方法。将DocumentBuilder存储为静态最终变量将有助于加快处理速度,因为您不需要每次都创建一个变量。

如果选择SAX,则应该扩展该类,就像该示例一样

import java.util.HashMap;
import java.util.Map;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class RowDefaultHandler extends DefaultHandler {

    @Override
    public void startElement(String uri, String localName, String qName,
            Attributes attributes) throws SAXException {
        if (!"row".equals(qName)) {
            return;
        }

        Map<String, String> row = new HashMap<String, String>();

        for (int i = 0; i < attributes.getLength(); i++) {
            row.put(attributes.getQName(i), attributes.getValue(i));
        }

        System.out.println(row);
    }

}

如果选择SAX,则应扩展该类,如该示例所示

import java.util.HashMap;
import java.util.Map;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class RowDefaultHandler extends DefaultHandler {

    @Override
    public void startElement(String uri, String localName, String qName,
            Attributes attributes) throws SAXException {
        if (!"row".equals(qName)) {
            return;
        }

        Map<String, String> row = new HashMap<String, String>();

        for (int i = 0; i < attributes.getLength(); i++) {
            row.put(attributes.getQName(i), attributes.getValue(i));
        }

        System.out.println(row);
    }

}

这在mrdp.utils中找到。其他人都是用核心Java编写的

public class MRDPUtils {

    public static final String[] REDIS_INSTANCES = { "p0", "p1", "p2", "p3",
            "p4", "p6" };

    // This helper function parses the stackoverflow into a Map for us.
    public static Map<String, String> transformXmlToMap(String xml) {
        Map<String, String> map = new HashMap<String, String>();
        try {
            String[] tokens = xml.trim().substring(5, xml.trim().length() - 3)
                    .split("\"");

            for (int i = 0; i < tokens.length - 1; i += 2) {
                String key = tokens[i].trim();
                String val = tokens[i + 1];

                map.put(key.substring(0, key.length() - 1), val);
            }
        } catch (StringIndexOutOfBoundsException e) {
            System.err.println(xml);
        }

        return map;
    }
}
公共类MRDPUtils{
公共静态最终字符串[]REDIS_实例={“p0”、“p1”、“p2”、“p3”,
“p4”、“p6”};
//这个助手函数为我们将stackoverflow解析为一个映射。
公共静态映射transformXmlToMap(字符串xml){
Map Map=newhashmap();
试一试{
String[]tokens=xml.trim().substring(5,xml.trim().length()-3)
.split(“\”);
对于(int i=0;i
这是在mrdp.utils中找到的。其他人都是用核心Java编写的

public class MRDPUtils {

    public static final String[] REDIS_INSTANCES = { "p0", "p1", "p2", "p3",
            "p4", "p6" };

    // This helper function parses the stackoverflow into a Map for us.
    public static Map<String, String> transformXmlToMap(String xml) {
        Map<String, String> map = new HashMap<String, String>();
        try {
            String[] tokens = xml.trim().substring(5, xml.trim().length() - 3)
                    .split("\"");

            for (int i = 0; i < tokens.length - 1; i += 2) {
                String key = tokens[i].trim();
                String val = tokens[i + 1];

                map.put(key.substring(0, key.length() - 1), val);
            }
        } catch (StringIndexOutOfBoundsException e) {
            System.err.println(xml);
        }

        return map;
    }
}
公共类MRDPUtils{
公共静态最终字符串[]REDIS_实例={“p0”、“p1”、“p2”、“p3”,
“p4”、“p6”};
//这个助手函数为我们将stackoverflow解析为一个映射。
公共静态映射transformXmlToMap(字符串xml){
Map Map=newhashmap();
试一试{
String[]tokens=xml.trim().substring(5,xml.trim().length()-3)
.split(“\”);
对于(int i=0;i
为什么不逐行将其解析为XML?另请参见。您还可以解释如何使用Hadoop和LineRecordReader构建一个逐行处理XML文件的框架。它一行一行地向我传递数据,并将其拆分为多个进程。相关:为什么不逐行将其解析为XML呢?另请参见。您还可以解释如何使用Hadoop和LineRecordReader构建一个逐行处理XML文件的框架。它一行一行地将数据传递给我,并将其拆分为多个进程。相关:我应该更清楚——我一次只能访问一行。并不是说我不想逐行处理它们,我必须这样做。尽管如此,您仍然可以使用SAX解析器,您只需要为每一行调用解析器。我认为这是可能的,但就性能而言,这不是一个好的解决方案。在这种情况下,手动解析将比SAX执行得更好