开发者

using xpath in java to go through this list?

开发者 https://www.devze.com 2023-01-22 17:37 出处:网络
i have an xml file that contains lots of different nodes. some in particularly are nested like this: <emailAddresses>

i have an xml file that contains lots of different nodes. some in particularly are nested like this:

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

From the above node, what i want to do is go through each and get the values inside it(value, typeSource, typeUser etc) and put them in a POJO.

i tried to see if i can use this xpath expression "//emailAddress" but it doesnt return me the tags inside inside it. maybe i am doing it wrong. i am pretty new to using xpath.

i could do something like this:

//emailAddress/value | //emailAddress/typeSource | .. but doi开发者_开发问答ng that will list all elements values together if im not mistaken leaving me to work out when i have finished reading from a specific emailAddress tag and going to the next emailAddress tag.

well to sum up my needs i basically want this to be returned similar to how you would return results from a bog standard sql query that returns results in a row. i.e. if your sql query produces 10 emailAddress, it will return each emailAddress in a row and i can simply iterate over "each emailAddress" and get the appropriate value based on the colunm name or index.


No,

//emailAddress

doesn't return the tags inside, that is correct. What it does return is a NodeList/NodeSet. To actually get the values you can do something like this:

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

Maybe I should point out that when iterating over the Nodelist, in .//values the first dot means the current context. Without the dot you would get the first node all the time.


//emailAddress/*

will get these nodes in the document order.

It depends on how you want to iterate through the nodes. We do all our XML using XOM (http://www.xom.nu/) which is an easy reliable Java package. It's possible to write your own strategy using XOM calls.


If you use XStream you can set it up quite easily. Like so:

@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
}

You then marshal & unmarshal quite simply like so:

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

IDK if you have to use XPath or not, but if not I'd consider an out of the box solution like this.


I am totally aware this is not what you were asking for, but may consider using jibx. This is a tool for human-readable XML to POJO mapping. So I believe you could generate mapping for your email structure in a quick way and let the jibx do the work for you.

0

精彩评论

暂无评论...
验证码 换一张
取 消