1

I need to get Device ID, DeviceType, data of first LastKnownValue tag. The XML is

<?xml version="1.0" encoding="utf-8"?>
  <DeviceList Devid="" Count="35">
    <Device ID="01">
      <Name>@@@@@</Name>
      <DeviceType>Me</DeviceType>
      <ValueVariables Count="3">
        <LastKnownValue Index="1" EndPoint="1" Name="STATE" Type="Bool">false</LastKnownValue>
        <LastKnownValue Index="2" EndPoint="1" Name="LOW BATTERY" Type="Bool">0</LastKnownValue>
        <LastKnownValue Index="3" EndPoint="1" Name="TAMPER" Type="Bool">false</LastKnownValue>
      </ValueVariables>
    </Device>
 </DeviceList>

I tried the following code, but unable to get the values of the attributes.

DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse("xml path");
doc.getDocumentElement().normalize();
NodeList devicelist =   doc.getDocumentElement().getElementsByTagName("Device");
System.out.println(devicelist.getLength());
for (int i = 0; i < devicelist.getLength(); ++i) 
{
        Element rule = (Element) devicelist.item(i);
        //Device ID
        String ruleid = rule.getAttribute("ID");
        System.out.println(ruleid);
}
mahi
  • 191
  • 1
  • 2
  • 16
  • As you see code in your comment is not that easy to read. So instead of posting it in comment use [[edit]] option to update your post and place it there with proper formatting. – Pshemo Apr 21 '15 at 08:42
  • Excuse me, why don't you use an XPath query?! – riccardo.cardin Apr 21 '15 at 08:49
  • I am unfamiliar to Xpath, please help me to get those attribute values. – mahi Apr 21 '15 at 08:51
  • You can find an example of use of XPath in this SO answer: [Get an Array or List of Strings between some Strings (Search multiple Strings)](https://stackoverflow.com/questions/29694064/get-an-array-or-list-of-strings-between-some-strings-search-multiple-strings/29694279#29694279) – riccardo.cardin Apr 21 '15 at 08:56

3 Answers3

1

I would recommend to use XPath to fetch the node values directly from XML instead of traverse and get desired node.

If Device node occurs only once then you can use below XPath expressions to fetch the data.

XPath to get Device ID is - //*/Device/@ID or /DeviceList/Device/@ID

XPath to get DeviceType is - //*/DeviceType or /DeviceList/Device/DeviceType

XPath to get first LastKnownValue - (//*/LastKnownValue)[1]

Sridhar
  • 1,832
  • 3
  • 23
  • 44
1

As stated in the comments, you can use an XPath query that will extract information directly from the doc.

Try to have a look at this link.

Here an example of code:

try {
   // Build structures to parse the String
   DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
   // Create an XPath query
   XPath xPath =  XPathFactory.newInstance().newXPath();
   // Query the DOM object with the query 
   NodeList nodeList = (NodeList) xPath.compile("//hello").evaluate(document, XPathConstants.NODESET);
 } catch (Exception e) {
     e.printStackTrace();
 }
riccardo.cardin
  • 7,971
  • 5
  • 57
  • 106
  • It is displaying following error:-[Fatal Error] :1:1: Content is not allowed in prolog. org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 1; Content is not allowed in prolog. – mahi Apr 21 '15 at 09:08
  • Are you sure that tour XML is a valid one? – riccardo.cardin Apr 21 '15 at 09:25
1

Completely functional example using JAXB:

public static void main(String[] args) throws Exception {
    JAXBContext ctx = JAXBContext.newInstance(DeviceList.class);
    Unmarshaller um = ctx.createUnmarshaller();
    DeviceList deviceList = (DeviceList) um.unmarshal(new File("example.xml"));
    for (Device device : deviceList.devices) {
        System.out.println(device.id);
        System.out.println(device.deviceType);
        if (device.valueVariables.lastKnownValues.size() > 0) {
            LastKnownValue lkv = device.valueVariables.lastKnownValues.get(0);
            System.out.println(lkv.value);
        }
    }
}

@XmlRootElement(name="DeviceList")
public class DeviceList {
    @XmlAttribute(name="Devid")
    public String devid;
    @XmlAttribute(name="Count")
    public Integer count;
    @XmlElement(name="Device")
    public List<Device> devices;
}

public class Device {
    @XmlAttribute(name="ID")
    public String id;
    @XmlElement(name="Name")
    public String name;
    @XmlElement(name="DeviceType")
    public String deviceType;
    @XmlElement(name="ValueVariables")
    public ValueVariables valueVariables;
}

public class ValueVariables {
    @XmlAttribute(name="Count")
    public Integer count;
    @XmlElement(name="LastKnownValue")
    public List<LastKnownValue> lastKnownValues;
}

public class LastKnownValue {
    @XmlAttribute(name="Index")
    public Integer index;
    @XmlAttribute(name="EndPoint")
    public Integer endPoint; // maybe a String?
    @XmlAttribute(name="Name")
    public String name;
    @XmlAttribute(name="Type")
    public String type;
    @XmlValue
    public String value;
}
Roger Gustavsson
  • 1,689
  • 10
  • 20