繁体   English   中英

使用Java中的XPATH处理分层XML文档。 效率?

[英]Processing a hierarchical XML Document with XPATH in Java. Efficiency?

这个问题的变体已经在这里被问过好几次了,但是我的问题更多是关于在Java中使用XPATH的一般效率的问题。

我的任务:获取有关地理位置的Wikipedia文章,并从中创建分层数据结构。

我已经获得了Wiki页面的XML版本,并根据直观的模式重新格式化了格式。 我还制作了一系列非常简单的类,分别表示不同层次的管理层次结构,例如:

public class Province implements java.io.Serializable {

private ArrayList<City> cities = new ArrayList<City>();
private String hanzi;
private String pinyin;


public Province(String hanzi, String pinyin) {
this.hanzi = hanzi;
this.pinyin = pinyin;
}

以及添加城市的方法,一些getter和setter方法以及toString()。

这是我正在处理的XML文件类型的示例:

<mediawiki>
     <page>
           <title>Tianjin</title>
           <revision>
                    <id>2064019</id>
                    <text xml:space="preserve">
                              <province>
                                       <hanzi>天津</hanzi>
                                       <pinyin>Tianjin</pinyin>

                                       <Level2>
                                               <hanzi>和平</hanzi>
                                               <pinyin>Heping</pinyin>
                                               <zip>300000</zip>
                                       </Level2>

                                       <Level2>
                                                <hanzi>河东</hanzi>
                                                <pinyin>Hedong</pinyin>
                                                <zip>300000</zip>
                                        </Level2>

                                </province>
                    </text>
            </revision>
      </page>

...

</mediawiki>

在这一点上,我基本上已经完成了功能设置,但是代码非常重复,并且没有考虑到地理数据固有的层次结构性质。 理想情况下,我可以停在某个级别(例如,“专注于”特定省份),并且仅从那时起以相对术语来指代事物,以最大程度地减少我必须遍历整个文档的次数。 作为示例(请注意,我在传统的Document设置上使用了抽象,但是下面的方法几乎完全与传统的方法相对应):

XPathReader reader = new XPathReader("sourceXML\\Provinces.xml");           
String expression = "/mediawiki/page";
NodeList allProvinces = (NodeList)reader.read(expression, XPathConstants.NODESET);

for(int i=0; i < allProvinces.getLength(); i++) {
     expression = "/mediawiki/page[" + i + "]/revision/text/province/hanzi";
     String hanzi = reader.read(expression, XPathConstants.STRING).toString();

     expression = "/mediawiki/page[" + i + "]/revision/text/province/pinyin";
     String pinyin = reader.read(expression, XPathConstants.STRING).toString();

     Province currProv = new Province(hanzi, pinyin);         



     expression = "/mediawiki/page[" + i + "]/revision/text/province/Level2";
     NodeList level2 = (NodeList)reader.read(expression, XPathConstants.NODESET);

     for(int j=1; j < level2.getLength(); j++) {
           expression = "/mediawiki/page[" + i + "]/revision/text/province/Level2[" + j + "]/hanzi";
           String hanzi2 = reader.read(expression, XPathConstants.STRING).toString();   

           expression = "/mediawiki/page[" + i + "]/revision/text/province/Level2[" + j + "]/pinyin";
           String pinyin2 = reader.read(expression, XPathConstants.STRING).toString();  

         City currCity = new City(hanzi2, pinyin2);
         currProv.add(currCity);
...
     }
}   

坦白说,这似乎很愚蠢。 我没有考虑到以下事实:一旦达到我所关注的级别,这些字符串的所有内容都是相同的。 我没有引用任何相对路径,并且每当遍历文档的一部分时,我实际上就遍历了整个过程。 如果我能将原始XML文档的其余部分拒之门外,只专注于我的省份,然后再以相对术语指代所有内容,那将是很好的。

我应该特别注意,“读取”抽象背后的成本是多少:

xPath.compile(expression);
String result = xPathExpression.evaluate (xmlDocument, returnType);

我本质上是在重新编译一个相同的模式,但结尾稍有不同吗? 加载感兴趣的部分,然后使用“ currProv / hanzi”之类的东西引用其子项,该怎么办?

我研究了解析XML的其他方法,“ Diggester”似乎与我想要的功能类似http://commons.apache.org/digester/core.html ,但是此XPATH中已经包含了几乎所有内容实施。

我有点怀疑这个问题的解决方案很简单...但是我不太了解解决方案。 无论如何,我感谢您的宝贵时间!

相对嵌套的XPath是必经之路。

我负责EclipseLink JAXB实现(MOXy),我们通过@XmlPath注释提供此功能。 如果您已经有了XPath,那将是一个相对容易的映射。

有关更多信息,请参见:

暂无
暂无

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

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