【问题标题】:XMLParsing, Dynamic Structure, ContentXMLParsing、动态结构、内容
【发布时间】:2018-05-02 10:47:19
【问题描述】:

想要实现:

获取未知 XML 文件的元素(元素名称,xml 文件中有多少元素)。

然后获取所有属性及其名称和值以供以后使用(例如与其他xml文件比较)

element_vs_attribute

研究: 1.2.3.4.5. 还有更多

有人对此有任何想法吗?

我不想像之前的代码 sn-p 那样预先定义超过 500 个表,我应该能够以某种方式动态获取元素的数量和元素名称。

编辑!

Example1
<Root Attri1="" Attri2="">
    <element1 EAttri1="" EAttri2=""/>
    <Element2 EAttri1="" EAttri2="">
        <nestedelement3 NEAttri1="" NEAttri2=""/>
    </Element2> 
</Root>

Example2
<Root Attri1="" Attri2="" Attr="" At="">
    <element1 EAttri1="" EAttri2="">
        <nestedElement2 EAttri1="" EAttri2="">
            <nestedelement3 NEAttri1="" NEAttri2=""/>
        </nestedElement2>
    </element1> 
</Root>

程序片段:

String Example1[] = {"element1","Element2","nestedelement3"};
String Example2[] = {"element1","nestedElement2","nestedelement3"};


for(int i=0;i<Example1.length;++){
    NodeList Elements = oldDOC.getElementsByTagName(Example1[i]);
    for(int j=0;j<Elements.getLength();j++) {
        Node nodeinfo=Elements.item(j);
        for(int l=0;l<nodeinfo.getAttributes().getLength();l++) {
        .....
    }
}

输出: 预期结果是从 XML 文件中获取所有元素和所有属性,而无需预先定义任何内容。

例如:

Elements: element1 Element2 nestedelement3

Attributes:  Attri1 Attri2 EAttri1 EAttri2 EAttri1 EAttri2 NEAttri1 NEAttri2

【问题讨论】:

  • 你可以使用 JAX-B,我想……我不是 100% 确定。
  • 你不需要密码sn-p,你需要一本书。我推荐 Elliot Rusty Harold 的关于 Java 中的 XML 处理的书。恐怕我将把它作为题外话来结束,因为这是一个“技术选择”问题,而且是题外话。但是,如果您搜索“Java 中的 XML 解析”,您会发现很多想法。
  • 这怎么可能是题外话?目前我正在使用 domparser 来解决这个问题,我最好的想法是在我预先定义元素之后进行多个 for 循环......我正在寻找的是一种通用且更简单的方法......如果那是题外话,那么我对此感到非常惊讶你的意见
  • 要将其变成一个合法的编程问题,您需要提供有关您的输入、您想要的输出、您到目前为止编写的代码以及您现有尝试未能解决问题的方式的具体信息问题。
  • 你去吧,希望它有助于理解我想要什么

标签: java xml domparser


【解决方案1】:

适合这项工作的工具是xpath 它允许您根据各种标准收集所有或部分元素和属性。这是最接近“通用”xml 解析器的方法。

这是我想出的解决方案。该解决方案首先在给定的 xml 文档中查找所有元素名称,然后对于每个元素,它会计算元素的出现次数,然后将其全部收集到地图中。属性相同。
我添加了内联 cmets 和方法/变量名称应该是不言自明的。

import java.io.*;
import java.nio.file.*;
import java.util.*;
import java.util.function.*;
import java.util.stream.*;

import org.w3c.dom.*;

import javax.xml.parsers.*;
import javax.xml.xpath.*;

public class TestXpath
{

    public static void main(String[] args) {

        XPath xPath = XPathFactory.newInstance().newXPath();

        try (InputStream is = Files.newInputStream(Paths.get("C://temp/test.xml"))) {
            // parse file into xml doc
            DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
            Document xmlDocument = builder.parse(is);

            // find all element names in xml doc
            Set<String> allElementNames = findNames(xmlDocument, xPath.compile("//*[name()]"));
            // for each name, count occurrences, and collect to map
            Map<String, Integer> elementsAndOccurrences = allElementNames.stream()
                .collect(Collectors.toMap(Function.identity(), name -> countElementOccurrences(xmlDocument, name)));
            System.out.println(elementsAndOccurrences);

            // find all attribute names in xml doc
            Set<String> allAttributeNames = findNames(xmlDocument, xPath.compile("//@*"));
            // for each name, count occurrences, and collect to map
            Map<String, Integer> attributesAndOccurrences = allAttributeNames.stream()
                .collect(Collectors.toMap(Function.identity(), name -> countAttributeOccurrences(xmlDocument, name)));
            System.out.println(attributesAndOccurrences);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static Set<String> findNames(Document xmlDoc, XPathExpression xpathExpr) {
        try {
            NodeList nodeList = (NodeList)xpathExpr.evaluate(xmlDoc, XPathConstants.NODESET);
            // convert nodeList to set of node names
            return IntStream.range(0, nodeList.getLength())
                .mapToObj(i -> nodeList.item(i).getNodeName())
                .collect(Collectors.toSet());
        } catch (XPathExpressionException e) {
            e.printStackTrace();
        }
        return new HashSet<>();
    }

    public static int countElementOccurrences(Document xmlDoc, String elementName) {
        return countOccurrences(xmlDoc, elementName, "count(//*[name()='" + elementName + "'])");
    }

    public static int countAttributeOccurrences(Document xmlDoc, String attributeName) {
        return countOccurrences(xmlDoc, attributeName, "count(//@*[name()='" + attributeName + "'])");
    }

    public static int countOccurrences(Document xmlDoc, String name, String xpathExpr) {
        XPath xPath = XPathFactory.newInstance().newXPath();
        try {
            Number count = (Number)xPath.compile(xpathExpr).evaluate(xmlDoc, XPathConstants.NUMBER);
            return count.intValue();
        } catch (XPathExpressionException e) {
            e.printStackTrace();
        }
        return 0;
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-01-30
    • 2012-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-06
    • 2020-10-04
    • 2012-03-12
    相关资源
    最近更新 更多