如何解析嵌套的XML数据并仅从中提取用户ID?

时间:2014-12-05 04:47:23

标签: java xml parsing sax

我有以下xml布局,我想从中提取所有&#34; userid&#34;值在<key> </key>内,并在Java中加载到HashSet

<?xml version="1.0" encoding="UTF-8"?>
<response>
   <plds>
      <fld>consumerid</fld>
      <fld>last_set</fld>
   </plds>
   <record>
      <data>934463448   1417753752</data>
      <key_data>
         <key>
            <name>userid</name>
            <value>934463448</value>
         </key>
      </key_data>
   </record>
   <record>
      <data>1228059948  1417753799</data>
      <key_data>
         <key>
            <name>userid</name>
            <value>1228059948</value>
         </key>
      </key_data>
   </record>
</response>

我将从url获取xml数据,并且我可以获得大的XML文件。解析上述XML并提取所有&#34; userid&#34;的最佳方法是什么?并将其加载到Java中的HashSet中?

这就是我的开始 -

public static Set<String> getUserList(String host, String count) {

    Set<String> usrlist = new HashSet<String>();
    String url = "urlA"; // this url will return me above XML data
    InputStream is = new URL(url).openStream();
    BufferedReader rd = new BufferedReader(new InputStreamReader(is, Charset.forName("UTF-8")));

    // not sure what I should do here which can
    // parse my above xml and extract all the
    // userid and load it into usrlist hash set

    return usrlist;
}

更新: -

这是我试过的 -

public static Set<String> getUserList() {

    Set<String> usrlist = new HashSet<String>();
    String url = "urlA"; // this url will return me above XML data
    InputStream is = new URL(url).openStream();
    BufferedReader rd = new BufferedReader(new InputStreamReader(is, Charset.forName("UTF-8")));

    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    DocumentBuilder builder = factory.newDocumentBuilder();
    Document doc = builder.parse(new URL(url).openStream());

    XPathFactory xPathfactory = XPathFactory.newInstance();
    XPath xpath = xPathfactory.newXPath();
    XPathExpression expr = xpath.compile("//record/key_data/key[name='userid']/value");
    NodeList nodes = (NodeList) expr.evaluate(doc, XPathConstants.NODESET);
    for (int i = 0; i < nodes.getLength(); i++) {
        usrlist.add(nodes.item(i).getNodeValue());
    }

    return usrlist;
}

但是我没有在usrlist对象中获得任何用户ID?我在这里做错了什么?

3 个答案:

答案 0 :(得分:3)

tAX是一种解析大型xml

的有效方法
    XMLStreamReader r = XMLInputFactory.newInstance().createXMLStreamReader(is);
    while(r.hasNext()) {
        if (r.next() == XMLStreamReader.START_ELEMENT && r.getLocalName().equals("value")) {
            String value = r.getElementText();
            System.out.println(value);
        }
    }

答案 1 :(得分:2)

如果上述文档相对较小,您可以load the entire document然后应用以下xpath来提取文档中的键:

//record/key_data/key[name='userid']/value

修改

我认为您有错误 - 使用getTextContent()获取text(),而不是getNodeValue()

for (int i = 0; i < nodes.getLength(); i++) {
    usrlist.add( nodes.item(i).getTextContent());
}

调试代码:

Set<String> usrlist = new HashSet<String>();
String myXml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
        "<response>\n" +
        ...
        "</response>";
InputStream is = new ByteArrayInputStream( myXml.getBytes( ) );
BufferedReader rd = new BufferedReader(new InputStreamReader(is, Charset.forName("UTF-8")));

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(new InputSource(rd));

XPathFactory xPathfactory = XPathFactory.newInstance();
XPath xpath = xPathfactory.newXPath();
XPathExpression expr = xpath.compile("//record/key_data/key[name='userid']/value");
NodeList nodes = (NodeList) expr.evaluate(doc, XPathConstants.NODESET);
for (int i = 0; i < nodes.getLength(); i++) {
    usrlist.add( nodes.item(i).getTextContent());
}

return usrlist;

答案 2 :(得分:0)

我现在相信JAXB是一种矫枉过正,而另外两个答案要好得多,但是既然你在JAXB上找了一个例子,我很乐意提供帮助。

您必须创建以下类,因此可以进行XML到Java对象的映射。

<强> Response.java

import java.util.List;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Response {

    List<Plds> pldslist;
    List<Record> recordlist;

    @XmlElement(name = "plds")
    public void setPlds(List<Plds> pldslist) {
        this.pldslist = pldslist;
    }

    public List<Plds> getPlds() {
        return pldslist;
    }

    @XmlElement(name = "record")
    public void setRecord(List<Record> recordlist) {
        this.recordlist = recordlist;
    }

    public List<Record> getRecord() {
        return recordlist;
    }

}

Record.java

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Record {

    String data;
    KeyData keyData;

    public String getData() {
        return data;
    }

    @XmlElement(name = "data")
    public void setData(String data) {
        this.data = data;
    }

    public KeyData getKeyData() {
        return keyData;
    }

    @XmlElement(name = "key_data")
    public void setKeyData(KeyData keyData) {
        this.keyData = keyData;
    }

}

<强> Plds.java

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Plds {

    private String fld;

    public String getFld() {
        return fld;
    }

    @XmlElement(name = "fld")
    public void setFld(String fld) {
        this.fld = fld;
    }

}

<强> KeyData.java

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class KeyData {

    Key key;

    public Key getKey() {
        return key;
    }

    @XmlElement(name = "key")
    public void setKey(Key key) {
        this.key = key;
    }
}

<强> Key.java

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Key {

    String name;
    String value;

    public String getName() {
        return name;
    }

    @XmlElement(name = "name")
    public void setname(String name) {
        this.name = name;
    }

    public String getValue() {
        return value;
    }

    @XmlElement(name = "value")
    public void setKey(String value) {
        this.value = value;
    }
}

示例Main.java

import java.io.File;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;


public class Main {

    public static void main(String[] args) 
    throws Exception
    {
        File file = new File("PATH_HERE/file.xml");
        JAXBContext jaxbContext = JAXBContext.newInstance(Response.class);

        Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
        Response response = (Response) jaxbUnmarshaller.unmarshal(file);
        for(Record rec : response.getRecord())
            System.out.println("Name : " + rec.getKeyData().getKey().getName() + " | " + "Value : " + rec.getKeyData().getKey().getValue());
    }

}