korunos
korunos

Reputation: 798

How to modify XML Attributes in Android/Java

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

Upvotes: 3

Views: 2063

Answers (1)

user5236059
user5236059

Reputation:

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());
    }
}

Upvotes: 1

Related Questions