3

I have this kind of XML File.

  <?xml version="1.0" encoding="utf-8"?>
<Test1>
<typ>task</typ>
  <datestamp>20150602153306</datestamp>
  <datecreate>20150602153306</datecreate>
<task uuid="92F7F685-C370-4E55-9026-020E3CDCEDE0" status="0">
    <task_headline>TEST2000</task_headline>
    <task_subject>There is a Problem.</task_subject>
    <task_action>Solve it!</task_action>
    <task_priority color="#E62C29">high</task_priority>
    <task_status>200</task_status>
    <task_note></task_note>
</task>
<task uuid="92F7F685-C370-4E55-9026-020E3CDCEDE0" status="0">
    <task_headline>TEST3000</task_headline>
    <task_subject>Another Problem</task_subject>
    <task_action>Solve it again.</task_action>
    <task_priority color="#E62C29">high</task_priority>
    <task_status>200</task_status>
</task>
</Test1>

This is a example File, so the uuid is in that case equal.

I want to search for a uuid and set the status to 1000.

What I have tried so far:

SAXBuilder builder = new 
org.jdom2.Document document = builder.build(new FileInputStream(new File(fileDir,filenameWithExt)));
org.jdom2.Element rootNode = document.getRootElement();
org.jdom2.Element task1 = rootNode.getChild("task");
task1.getAttribute(taskItems.get(position).get(task_uuid)).setValue("1000");

This is how I create the File:

TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(new FileOutputStream(new File(fileDir, filenameWithExt)));
transformer.transform(source, result);

But this still not works. How can I search for an Attribute to edit another Attribute?

I hope you understand what I want to do.

Kind Regards

2
  • Do you want to edit the Objects and then use them in your program, or do you want to save them to the file again after the edit? Commented Aug 18, 2015 at 9:26
  • Yes i want to save it later to the file. i add the code for creation a file Commented Aug 18, 2015 at 9:27

1 Answer 1

1

I understand your question as follows: You want to select a task with a given UUID and then you want to change the status attribute of that task element.

These are actually two steps and I suggest you separate them:

(1) Find the task element with a given UUID

The easiest way of doing this is to use an XPath expression, which allows you to declaratively state which elements you want to select. For the given XML structure you can use the following XPath:

"/Test1/task[@uuid=\"92F7F685-C370-4E55-9026-020E3CDCEDE0\"]"

This XPath starts at the root node Test1 and then selects all task child nodes which fulfill the predicate given in the brackets. There, @uuid refers to the attribute uuid which is required to be equal to the given UUID.

(2) Get the attribute you want to change

So far our XPath selects the right task element. But what we are actually interested in this elements status attribute. So lets add another little piece selecting this attribute

"/Test1/task[@uuid=\"92F7F685-C370-4E55-9026-020E3CDCEDE0"/@status]"

You see, selecting child nodes can be done using a backslash analog to the navigation inside a directory structure. Attributes are marked by an @ sign, elements just by their name without the @ sign. Predicates for selecting subsets of nodes can be given in brackets.

In JDOM, we can evaluate this XPath expression with the following code:

XPathFactory xpf = XPathFactory.instance();
XPathExpression<Attribute> xpath = xpf.compile(
            "/Test1/task[@uuid=\"92F7F685-C370-4E55-9026-020E3CDCEDE0\"]/@status",
            Filters.attribute(), null);

Attribute taskStatus = xpath.evaluateFirst(doc);

(3) Change the value of the attribute we just selected

This is as simple as calling the setValue method of the attribute element.

taskStatus.setValue("1000");

Here's a complete and running example which outputs the value of the attribute before and after the change:

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

import org.jdom2.Attribute;
import org.jdom2.Document;
import org.jdom2.JDOMException;
import org.jdom2.filter.Filters;
import org.jdom2.input.SAXBuilder;
import org.jdom2.xpath.XPathExpression;
import org.jdom2.xpath.XPathFactory;

public class ChangeXMLAttribute {

    public static void changeAttribute() throws FileNotFoundException, JDOMException, IOException {
        SAXBuilder builder = new SAXBuilder();
        Document doc = builder.build(new FileInputStream(new File("path/to/directory","filename")));

        XPathFactory xpf = XPathFactory.instance();
        XPathExpression<Attribute> xpath = xpf.compile(
                "/Test1/task[@uuid=\"92F7F685-C370-4E55-9026-020E3CDCEDE0\"]/@status",
                Filters.attribute(), null);

        Attribute taskStatus = xpath.evaluateFirst(doc);

        System.out.println("Before: " + taskStatus.getValue());

        taskStatus.setValue("1000");

        System.out.println("After: " + taskStatus.getValue());
    }
}
Sign up to request clarification or add additional context in comments.

3 Comments

Can you tell me how i can append a child if for example the tag <task_note> is missing like in the second segment of my xml file. I mean i want to check if the tag is missing and if true then add the element
Assume the variable task refers to the task xml element. Then you can use if (task.getChild("task_note") == null) { Element note = new Element("task_note"); task.addContent(note); }.
Can you let me know how to save the change you made (setValue) to the same xml file(source file)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.