代码之家  ›  专栏  ›  技术社区  ›  Jono

在java中使用xpath浏览这个列表?

  •  1
  • Jono  · 技术社区  · 15 年前

    我有一个包含许多不同节点的xml文件。特别是一些嵌套如下:

     <emailAddresses>
                <emailAddress>
                    <value>sambj1981@gmail.com</value>
                    <typeSource>WORK</typeSource>
                    <typeUser></typeUser>
                    <primary>false</primary>
                </emailAddress>
                <emailAddress>
                    <value>sambj@hotmail.co.uk</value>
                    <typeSource>HOME</typeSource>
                    <typeUser></typeUser>
                    <primary>true</primary>
                </emailAddress>
            </emailAddresses>
    

    在上面的节点中,我要做的是遍历每个节点并获取其中的值(value、typeSource、typeUser等),然后将它们放入POJO中。

    我试着看看是否可以使用这个xpath表达式 "//emailAddress" 但它不会把里面的标签还给我。也许我做错了。我对使用xpath很陌生。

    我可以这样做:

    //emailAddress/value | //emailAddress/typeSource | .. 但如果我没有弄错的话,这样做会把所有元素的值都列在一起,让我在读完一个特定的emailAddress标记并转到下一个emailAddress标记后再计算。

    为了总结我的需求,我基本上希望返回的结果类似于您将如何返回来自bog标准sql查询的结果,该查询将返回一行结果。i、 e.如果你的sql查询生成10个emailAddress,它将返回一行中的每个emailAddress,我可以简单地遍历“每个emailAddress”,并根据colunm名称或索引获得适当的值。

    4 回复  |  直到 15 年前
        1
  •  3
  •   Kennet    15 年前

    不,

    //电子邮件地址

    不返回内部标记,这是正确的。它返回的是NodeList/NodeSet。要实际获得这些值,可以执行以下操作:

    String emailpath = "//emailAddress";
    String emailvalue = ".//value";
    
    XPathFactory xPathFactory = XPathFactory.newInstance();
    XPath xpath = xPathFactory.newXPath();
    Document document;
    public XpathStuff(String file) throws ParserConfigurationException, IOException, SAXException {
        DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = docFactory.newDocumentBuilder();
    
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
        document = builder.parse(bis);
    
        NodeList nodeList = getNodeList(document, emailpath);
        for(int i = 0; i < nodeList.getLength(); i++){
            System.out.println(getValue(nodeList.item(i), emailvalue));
        }
        bis.close();        
    }
    
    public NodeList getNodeList(Document doc, String expr) {
        try {
            XPathExpression pathExpr = xpath.compile(expr);
            return (NodeList) pathExpr.evaluate(doc, XPathConstants.NODESET);
        } catch (XPathExpressionException e) {
            e.printStackTrace();
        }
        return null;
    }
    
    
    //extracts the String value for the given expression
    private String getValue(Node n, String expr) {
        try {
            XPathExpression pathExpr = xpath.compile(expr);
            return (String) pathExpr.evaluate(n,
                    XPathConstants.STRING);
        } catch (XPathExpressionException e) {
            e.printStackTrace();
        }
        return null;
    }
    

    也许我应该指出,当在Nodelist上迭代时,in。//values第一个点表示当前上下文。如果没有这个点,你会一直得到第一个节点。

        2
  •  2
  •   peter.murray.rust    15 年前
    //emailAddress/*
    

    将按文档顺序获取这些节点。

    这取决于您希望如何遍历节点。我们使用XOM(http://www.XOM.nu/)来完成所有的XML,XOM是一个简单可靠的Java包。可以使用XOM调用编写自己的策略。

        3
  •  2
  •   javamonkey79    15 年前

    @XStreamAlias( "EmailAddress" )
    public class EmailAddress {
    
       @XStreamAlias()
       private String value;
    
       @XStreamAlias()
       private String typeSource;
    
       @XStreamAlias()
       private String typeUser;
    
       @XStreamAlias()
       private boolean primary;
    
       // ... the rest omitted for brevity
    }
    

    然后,您可以很简单地封送和解封:

    XStream xstream = new XStream();
    xstream.processAnnotations( EmailAddress.class );
    xstream.toXML( /* Object value here */ emailAddress );
    xstream.fromXML( /* String xml value here */ "" );
    

    不得不 不管是否使用XPath,如果不使用,我会考虑这样一个开箱即用的解决方案。

        4
  •  0
  •   Grzegorz Oledzki    15 年前

    我完全知道这不是你想要的,但是可以考虑使用 jibx 因此,我相信您可以快速生成电子邮件结构的映射,并让jibx为您完成工作。