简体   繁体   English

用Java展平XML文档

[英]Flatten XML document in Java

Is there any way to Flatten an XML document by removing all the nested tags / arrays to simple Key / Value pair. 有什么方法可以通过将所有嵌套的标签/数组移除为简单的键/值对来展平XML文档。 For example I have an example 例如我有一个例子

<root>
<a>
    <b>some-value1</b>
    <c>some-value2</c>
</a>
<a>
    <b>some-value3</b>
    <c>some-value4</c>
</a>
<p>some-value-p</p>

TO

root.a.0.b=some-value1
root.a.0.c=some-value2
root.a.1.b=some-value3
root.a.1.c=some-value4
root.p=some-value-p

I am looking for some solution in Java or Scala? 我在寻找Java或Scala的解决方案?

You could use Jackson 你可以用杰克逊

Instead of 代替

root.a.0.b=some-value1
root.a.0.c=some-value2
root.a.1.b=some-value3
root.a.1.c=some-value4
root.p=some-value-p

You will get 你会得到

#converted XML
#Tue Sep 19 15:15:57 CEST 2017
a.2.c=some-value4
a.2.b=some-value3
p=some-value-p
a.1.c=some-value2
a.1.b=some-value1

Here is test code: 这是测试代码:

import com.fasterxml.jackson.dataformat.javaprop.JavaPropsMapper;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
import java.io.IOException;
import java.io.StringReader;
import java.util.List;
import java.util.Properties;
import org.junit.Test;

public class TestXMLConversion {
    public static final String XML =
"<root>\n" +
"<a>\n" +
"    <b>some-value1</b>\n" +
"    <c>some-value2</c>\n" +
"</a>\n" +
"<a>\n" +
"    <b>some-value3</b>\n" +
"    <c>some-value4</c>\n" +
"</a>\n" +
"<p>some-value-p</p>" +
"</root>";

    public static class Root {
        @JacksonXmlElementWrapper(useWrapping=false)
        private List<A> a;
        private String p;

        public List<A> getA() {
            return a;
        }

        public void setA(List<A> a) {
            this.a = a;
        }

        public String getP() {
            return p;
        }

        public void setP(String p) {
            this.p = p;
        }
    }

    public static class A {
        private String b;
        private String c;

        public String getB() {
            return b;
        }

        public void setB(String b) {
            this.b = b;
        }

        public String getC() {
            return c;
        }

        public void setC(String c) {
            this.c = c;
        }
    }

    @Test
    public void test() throws IOException {
        XmlMapper xmlMapper = new XmlMapper();
        Root parsedData = xmlMapper.readValue(new StringReader(XML), Root.class);

        JavaPropsMapper propertiesMapper = new JavaPropsMapper();
        Properties properties = propertiesMapper.writeValueAsProperties(parsedData);

        properties.store(System.out, "converted XML");
    }
}

The dependencies I used: 我使用的依赖项:

<dependency>
    <groupId>com.fasterxml.jackson.dataformat</groupId>
    <artifactId>jackson-dataformat-xml</artifactId>
    <version>2.9.1</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.dataformat</groupId>
    <artifactId>jackson-dataformat-properties</artifactId>
    <version>2.9.1</version>
</dependency>
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
    <scope>test</scope>
</dependency>

Here is a solution without external dependencies. 这是没有外部依赖性的解决方案。 You can try it ! 你可以试试看

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;

public class Main {

    private static final String xml = 
            "<root>\n" +
            "    <a>\n" +
            "        <b>some-value1</b>\n" +
            "        <c>some-value2</c>\n" +
            "    </a>\n" +
            "    <a>\n" +
            "        <b>some-value3</b>\n" +
            "        <c>some-value4</c>\n" +
            "    </a>\n" +
            "    <p>some-value-p</p>\n" +
            "</root>";

    public static void main(String[] args) {
        try {
            byte[] bytes = xml.getBytes(StandardCharsets.UTF_8);
            try (InputStream input = new ByteArrayInputStream(bytes)) {
                Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(input);
                Element root = document.getDocumentElement();
                flattXml("", root);
            }
        } catch (IOException | ParserConfigurationException | SAXException e) {
            e.printStackTrace();
        }
    }

    private static void flattXml(String currentPath, Node currentNode) {
        if (currentNode.getNodeType() == Node.TEXT_NODE &&
                !currentNode.getNodeValue().trim().isEmpty()) {
            System.out.println(currentPath + "=" + currentNode.getNodeValue());
        } else {
            NodeList childNodes = currentNode.getChildNodes();
            int length = childNodes.getLength();
            String nextPath = currentPath.isEmpty()
                    ? currentNode.getNodeName()
                    : currentPath + "." + currentNode.getNodeName();
            for (int i = 0; i < length; i++) {
                Node item = childNodes.item(i);
                flattXml(nextPath, item);
            }
        }
    }

}

Console output: 控制台输出:

root.a.b=some-value1
root.a.c=some-value2
root.a.b=some-value3
root.a.c=some-value4
root.p=some-value-p

Parse the XML, then recursively step through the node tree keeping track of the parent. 解析XML,然后递归地浏览节点树并跟踪父节点。 Then print parent + "." 然后打印父+“。 + node + "=" + value. +节点+“ =” +值。

If you are going through the trouble of converting it though, it may be easier just to parse it directly into a useful object though using something like Jackson. 如果您遇到转换麻烦,可以使用Jackson之类的方法将其直接解析为有用的对象会更容易。 Then you can account for things like attributes in the XML. 然后,您可以考虑诸如XML中的属性之类的事情。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM