java—是否可以在没有嵌套循环的情况下读取整个xml文件

qf9go6mv  于 2021-08-25  发布在  Java
关注(0)|答案(1)|浏览(388)

我是xml新手,我想在一项任务中得到帮助。我需要为xml文件编写一个解析器(见下文)。解析器应该返回 HashTable<String, List<String>> 其中key是action name,列表中包含的参数名称的顺序与这些名称在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());
                }
         }            
    }

代码可以工作,但它非常庞大,有两个嵌套循环。有没有更有效、更简单的方法来实现所需的功能?提前谢谢。

v440hwme

v440hwme1#

您可以考虑用XxPath 3.1移动到Sxon 10他(或者SAXON 9.8或9.9 HE),然后您的XPath将是简单的。

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

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

然后使用s9api,它应该能够从xpath 3.1 xdmMap到java哈希表,或者简单地使用xdmMap:

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);

相关问题