It is necessary to find the Node in xml and get some information from it in the future. Decided to use XPath.

Here is the xml fragment. It is necessary to find and get message with some id .

 <messages> <message id="afbaee5e-d537-44eb-abb1-365d9ffac99a"> <author>slawiko</author> <text>Hello</text> <date>30-04-2015 15:57</date> <method>post</method> </message> <message id="e8ffe31a-0c4f-490c-aafc-fa9599339de2"> <author>slawiko</author> <text>How are you?</text> <date>30-04-2015 15:57</date> <method>post</method> </message> </messages> 

Here is the function in which I am trying to implement this:

 private static synchronized Node getNodeById(Document document, String id) throws XPathExpressionException, IOException, SAXException, ParserConfigurationException { XPath xpath = XPathFactory.newInstance().newXPath(); String expression = "//" + "message" + "[@id='" + id + "']"; XPathExpression expr = xpath.compile(expression); Node node = (Node) expr.evaluate(document, XPathConstants.NODE); return node; } 

The Node object returned by this function is passed to the function:

 public static Message nodeToMessage(Node node) { NodeList childNodes = node.getChildNodes(); Element element = (Element)node; String id = element.getAttribute(ID); String author = null; String text = null; String date = null; int length = childNodes.getLength(); for (int i = 0; i < length; i++) { if (AUTHOR.equals(childNodes.item(i).getNodeName())) { author = childNodes.item(i).getNodeValue(); } else if (TEXT.equals(childNodes.item(i).getNodeName())) { text = childNodes.item(i).getNodeValue(); } else if (DATE.equals(childNodes.item(i).getNodeName())) { date = childNodes.item(i).getNodeValue(); } } Message message = new Message(id, author, text, date); return message; } 

Probably this Node goes wrong. Later, when I debug the code, on the type reduction line, the debug just stops.

In addition, the nodeToMessage function does not work at all as I would like:
childeNodes.getLength() returns the number 9, although it is clear that it should return 4. From this, they make another conclusion: something is wrong with Node.

So the question is: what is wrong here? And if this is the case, where could the problem be?

  • Check which package you are using with xpath. Apparently javax.xml.xpath, but there are certain doubts ... - Yura Ivanov

1 answer 1

Discarded this idea. I decided that I did not need to get the Node. I just started to change the XML inside the desired Node. At that moment I realized that I understood the structure of the XML document incorrectly. Already with all the edits, the replacement process looks like this (it works correctly):

  DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); Document document = documentBuilder.parse(STORAGE_LOCATION); document.getDocumentElement().normalize(); Node messageToUpdate = getNodeById(document, message.getId()); if (messageToUpdate != null) { NodeList childNodes = messageToUpdate.getChildNodes(); for (int i = 0; i < childNodes.getLength(); i++) { Node node = childNodes.item(i); if (TEXT.equals(node.getNodeName())) { node.setTextContent(message.getText()); } } Transformer transformer = getTransformer(); DOMSource source = new DOMSource(document); StreamResult result = new StreamResult(new File(STORAGE_LOCATION)); transformer.transform(source, result); } else { throw new NullPointerException(); } 

Accordingly, in the function getNodeById did not change anything.