Harsh
Harsh

Reputation: 25

How to write to XML document at specific element with specific attribute?

The structure of my XML document is:

<?xml version="1.0" encoding="UTF-8"?>
<PasswordVault>
  <User id="1">
    <Log LOG="1">
      <AccountType>a</AccountType>
      <Username>a</Username>
      <Password>a</Password>
      <E-mail>a</E-mail>
    </Log>
    <Log Log="2">
      <AccountType>b</AccountType>
      <Username>b</Username>
      <Password>b</Password>
      <E-mail>b</E-mail>
    </Log>
  </User>
  <User id="2">
    <Log LOG="2">
      <AccountType>a</AccountType>
      <Username>a</Username>
      <Password>a</Password>
      <E-mail>a</E-mail>
    </Log>
  </User>
</PasswordVault>

I am trying to add code in Java that is able to write another Log element with another attribute assigned to it and the the other elements within it. However it must be within the correct User element that is the attribute where id = "2". I have been using JDOM and SAX but i cannot seem to find a tutorial that demonstrates how to do this.

public static void editXML(String inpName,String inpPassword,String inpEmail,String inpAccountType) {
      try {

            SAXBuilder builder = new SAXBuilder();
            File xmlFile = new File("FILE PATH");

            Document doc = (Document) builder.build(xmlFile);
            Element rootNode = doc.getRootElement();

            // PROBLEM HERE - dont know how to find element by specific attribute
            Element user = rootNode.getChild("User");



            // add new element
            // hard coded just to test it
            Element newLog = new Element("Log").setAttribute("Log","1");

            // new elements 
            Element accountType = new Element("AccountType").setText(inpAccountType);
            newLog.addContent(accountType);

            Element name = new Element("Username").setText(inpName);
            newLog.addContent(name);

            Element password = new Element("Password").setText(inpPassword);
            newLog.addContent(password);                

            Element email = new Element("E-mail").setText(inpEmail);
            newLog.addContent(email);

            user.addContent(newLog);

            XMLOutputter xmlOutput = new XMLOutputter();

            // display nice nice
            xmlOutput.setFormat(Format.getPrettyFormat());
            xmlOutput.output(doc, new FileWriter("FILE PATH"));

            // xmlOutput.output(doc, System.out);

            System.out.println("File updated!");
          } catch (IOException io) {
            io.printStackTrace();
          } catch (JDOMException e) {
            e.printStackTrace();
          }


}

I have head about Xpath but i am very unfamiliar and i could not find much online that related to my situation.

Upvotes: 0

Views: 66

Answers (1)

Sajith Edirisinghe
Sajith Edirisinghe

Reputation: 1727

You can filter out the User element with id attribute 2 with below code.

final Optional<Element> userNode = rootNode.getChildren("User").stream()
            .filter(user -> "2".equals(user.getAttributeValue("id"))).findFirst();

After that you need to check if the user element is present as below

Element user = null;
if (userNode.isPresent()) {
    user = userNode.get();
} else {
    //handle failure
}

if (user != null) {
    // create new elements and rest of the logic
}

Upvotes: 1

Related Questions