используя xpath в Java, чтобы пройти через этот список? - PullRequest
1 голос
/ 01 ноября 2010

У меня есть 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.

хорошо, чтобы подвести итог моим потребностям, я в основном хочу, чтобы это возвращалось подобно тому, как вы будете возвращать результаты из стандартного SQL-запроса, который возвращаетрезультаты подряд.т. е. если ваш sql-запрос выдаст 10 emailAddress, он будет возвращать каждый emailAddress подряд, и я могу просто перебрать «каждый emailAddress» и получить соответствующее значение на основе имени или индекса столбца.

Ответы [ 4 ]

3 голосов
/ 01 ноября 2010

Нет,

// emailAddress

не возвращает теги внутрь, это правильно.Что он возвращает, так это 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, в .//values ​​первая точка означает текущий контекст.Без точки вы бы все время получали первый узел.

2 голосов
/ 01 ноября 2010

Если вы используете XStream, вы можете настроить его довольно легко. Вот так:

@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 */ "" );

IDK, если вам нужно использовать XPath или нет, но если нет, я бы рассмотрел готовое решение, подобное этому.

2 голосов
/ 01 ноября 2010
//emailAddress/*

получит эти узлы в порядке документа.

Это зависит от того, как вы хотите перебирать узлы. Мы выполняем весь наш XML с использованием XOM (http://www.xom.nu/), который является простым надежным пакетом Java. Можно написать собственную стратегию с использованием вызовов XOM.

0 голосов
/ 01 ноября 2010

Я полностью осознаю, что это не то, что вы просили, но, возможно, рассмотрите возможность использования jibx . Это инструмент для удобочитаемого отображения XML на POJO. Поэтому я считаю, что вы можете быстро сгенерировать сопоставление для своей структуры электронной почты и позволить Jibx сделать всю работу за вас.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...