问题
I am making a video converter as a holiday project. I was planning on using an XML file to represent the pending tasks so the user can save the tasks. here is what it will look like:
<?xml version="1.0" ?>
<task-list>
<task>
<input-location> </input-location>
<output-location> </output-location>
<bit-rate> </bit-rate>
<output-width> </output-width>
<output-height> </output-height>
<target-device> </target-device>
</task>
.
.
.
.
</task-list>
Now, here is what I have in mind:
1. Parse this to a org.w3c.dom.Document
2. Use XPath to get a NodeList
which will contain all <task>
and it's children.
3. Create a Vector<Task>
where Task
is a custom class. Each Task
object will contain a org.w3c.dom.Node
4. Use XPath in context of the Node
associated with each Task
object to obtain relevant information.
But here is a problem: How do I mutate the Node
? Maybe the user wants to change the output location. I will have to make the changes to the concerned Task
object's Node
, the org.w3c.dom.Document
(which also holds a copy of the Node from the saved file) and save it to the file (for consistency the next time the converter is run).
This would get very cumbersome using XPath. XPath is good for data 'recovery' but not for changing, I presume.
public class Task
public class Task{
Node taskInfo;
JProgressBar progressBar; // Visual feedback to the user
.
.
.
.
.
// getters and setters
}
I can make getters work using XPath. Setters are the problem.
回答1:
You could do the following with any JAXB (JSR-222) implementation. An implementation is included in the JDK/JRE starting with Java SE 6:
JAVA MODEL
TaskList
import java.util.List;
import javax.xml.bind.annotation.*;
@XmlRootElement(name="task-list")
@XmlAccessorType(XmlAccessType.FIELD)
public class TaskList {
@XmlElement(name="task")
private List<Task> tasks;
}
Task
import javax.xml.bind.annotation.*;
@XmlAccessorType(XmlAccessType.FIELD)
public class Task {
@XmlElement(name="input-location")
private String inputLocation;
@XmlElement(name="output-location")
private String outputLocation;
@XmlElement(name="bit-rate")
private int bitRate;
@XmlElement(name="output-width")
private int outputWidth;
@XmlElement(name="output-height")
private int outputHeight;
@XmlElement(name="target-device")
private String targetDevice;
}
DEMO CODE
Demo
import java.io.File;
import javax.xml.bind.*;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(TaskList.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
File xml = new File("src/forum16579050/input.xml");
TaskList taskList = (TaskList) unmarshaller.unmarshal(xml);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(taskList, System.out);
}
}
input.xml/Output
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<task-list>
<task>
<input-location>foo input</input-location>
<output-location>foo output</output-location>
<bit-rate>1</bit-rate>
<output-width>2</output-width>
<output-height>3</output-height>
<target-device>foo</target-device>
</task>
<task>
<input-location>bar input</input-location>
<output-location>bar output</output-location>
<bit-rate>4</bit-rate>
<output-width>5</output-width>
<output-height>6</output-height>
<target-device>bar</target-device>
</task>
</task-list>
回答2:
- take a look at Apache Digester
- create a schema for your XML and process that schema into classes (which will be JAXB annotated), and then XML will become java objects much more easily (JAXB documentation will tell everything)
来源:https://stackoverflow.com/questions/16579050/how-do-i-efficiently-manage-the-various-conversion-tasks