Using Java to parse XML
java, php, xml
Solution
The easiest way, if performance is not a main concern, is probably XPath. With XPath, you can find nodes and attributes simply by specifying a path.
XPathFactory xPathfactory = XPathFactory.newInstance();
XPath xpath = xPathfactory.newXPath();
XPathExpression expr = xpath.compile(<xpath_expression>);
NodeList nl = (NodeList) expr.evaluate(doc, XPathConstants.NODESET);
The xpath_expression could be as simple as
"string(//member/observedProperty/@href)"
For more information about XPath, XPath Tutorial from W3Schools is pretty good.
Problem
I have made a PHP script that parses an XML file. This is not easy to use and I wanted to implement it in Java. Inside the first element there are various count of `wfs:member` elements I loop through: ``` foreach ($data->children("wfs", true)->member as $member) { } ``` This was easy to do with Java: ``` NodeList wfsMember = doc.getElementsByTagName("wfs:member"); for(int i = 0; i < wfsMember.getLength(); i++) { } ``` I have opened the XML file like this ``` DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); Document doc = documentBuilder.parse(WeatherDatabaseUpdater.class.getResourceAsStream("wfs.xml")); ``` Then I need to get a attribute from an element called `observerdProperty`. In PHP this is simple: ``` $member-> children("omso", true)->PointTimeSeriesObservation-> children("om", true)->observedProperty-> attributes("xlink", true)->href ``` But in Java, how do I do this? Do I need to use `getElementsByTagName` and loop through them if I want to go deeper in the structure?` In PHP the whole script looks the following. ``` foreach ($data->children("wfs", true)->member as $member) { $dataType = $dataTypes[(string) $member-> children("omso", true)->PointTimeSeriesObservation-> children("om", true)->observedProperty-> attributes("xlink", true)->href]; foreach ($member-> children("omso", true)->PointTimeSeriesObservation-> children("om", true)->result-> children("wml2", true)->MeasurementTimeseries-> children("wml2", true)->point as $point) { $time = $point->children("wml2", true)->MeasurementTVP->children("wml2", true)->time; $value = $point->children("wml2", true)->MeasurementTVP->children("wml2", true)->value; $data[$dataType][] = array($time, $value) } } ``` In the second `foreach` I loop through the observation elements and get the time and value data from it. Then I save it in an array. If I need to loop through the elements in Java the way I described, this is very hard to implement. I don't think that is the case, so could someone advice me how to implement something similar in Java?