【问题标题】:Is it possible to read whole XML file without nested loops是否可以在没有嵌套循环的情况下读取整个 XML 文件
【发布时间】:2021-09-17 00:55:28
【问题描述】:

我是 XML 新手,我想获得有关任务的帮助。我需要为 XML 文件编写一个解析器(见下文)。解析器应返回HashTable<String, List<String>>,其中键是操作名称,列表包含参数名称,其顺序与这些名称在 XML 文件中出现的顺序相同。这里最重要的是参数名称的顺序。 XML:

....
<actions>
    <action>
            <name>ActionName1</name>
            <arguments>
                <argument>
                    <name>name1</name>
                    <type>type1</type>
                    <comment>comment</comment>
                </argument>
                 <argument>
                      <name>name2</name>
                      <type>type2</type>
                      <comment>comment</comment>
                 </argument>
                   <argument>
                       <name>name3</name>
                       <type>type3</type>
                       <comment>comment</comment>
                   </argument>
            </arguments>
        </action>
        <action>
            <name>ActionName2</name>
            <arguments>
                  ...
            </arguments>
        </action>   
 </actions>

代码:

 ...   
    String expression = "//actions/action";
    XPathExpression compiled = xPath.compile(expression);
    nodeList = (NodeList) compiled.evaluate(document, XPathConstants.NODESET);
 
    for (int i = 0; i < nodeList.getLength(); i++) {
                 
         Node node = nodeList.item(i);
         NodeList children = node.getChildNodes();
                 
         for (int j = 0; j < children.getLength(); j++) {
              Node child = children.item(j);
              
              if (child.getNodeName().equals("name")) {
                //add new entry to map, meanwhile just print it
                 System.out.println(child.getTextContent());
                 continue;
              }
              
              if (child.getNodeName().equals("arguments")) {
                Element element = (Element) child;
                NodeList names = element.getElementsByTagName("name");
                for (int k = 0; k < names.getLength() ; k++) {
                     Node nameNode = names.item(k);
                     //add element to list, meanwhile print it
                     System.out.println("\t" + nameNode.getTextContent());
                }
         }            
    }

代码可以运行,但它非常庞大并且有 2 个嵌套循环。 有没有更有效和简单的方法来实现所需的功能? 提前致谢。

【问题讨论】:

    标签: java xml dom xpath


    【解决方案1】:

    您可以考虑使用 Saxon 10 HE(或 Saxon 9.8 或 9.9 HE)迁移到 XPath 3.1,然后您的 XPath 将变得简单

    map:merge(//action!map { name : arguments/argument/name/string() })
    

    map:merge(//action!map { name : array { arguments/argument/name/string() }})
    

    然后使用 s9api 它应该能够从 XPath 3.1 XDM 映射到您的 Java HashTable 或简单地使用 XDM 映射:

        Processor processor = new Processor(true);
    
        DocumentBuilder docBuilder = processor.newDocumentBuilder();
    
        XdmNode input = docBuilder.build(new File("sample-actions1.xml"));
    
        XPathCompiler xpathCompiler = processor.newXPathCompiler();
    
        xpathCompiler.declareNamespace("map", "http://www.w3.org/2005/xpath-functions/map");
    
        XdmMap result = (XdmMap)xpathCompiler.evaluateSingle("map:merge(//action!map { string(name) : arguments/argument/name/string() })", input);
    
        System.out.println(result);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多