是否可以在没有嵌套循环的情况下读取整个 XML 文件
Posted
技术标签:
【中文标题】是否可以在没有嵌套循环的情况下读取整个 XML 文件【英文标题】:Is it possible to read whole XML file without nested loops 【发布时间】: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 个嵌套循环。 有没有更有效和简单的方法来实现所需的功能? 提前致谢。
【问题讨论】:
【参考方案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);
【讨论】:
以上是关于是否可以在没有嵌套循环的情况下读取整个 XML 文件的主要内容,如果未能解决你的问题,请参考以下文章