xstream: only parsing child element - java

I have following xml
<root>
<child-1>
</child-1>
<child-2>
<subchild-21>
</subchild-22>
</child-2>
</root>
My requirement is such that I only want to parse child-2. I am unaware of root and child-1.
Is it possible with xstream because I couldn't find a way to ignore root.

There are several ways to go, depending on your requirements.
If you know the name of the class to parse (child-2 here), you could look for the <child-2> and </child-2> entry in the XML, copy them along with the content in-between to a new temporary XML file (you can create temporary files using createTempFile() from the standard File class). This is the way I would suggest.
If you want to take out the child-2 instance without knowing its name, but you know the names of the surrounding classes, you could mock their classes, that is create classes of the same name, but without their specific content. In your example there is no content (might have been ignored at export time), but it's important to have the same member data in the mock classes for the import to succeed. (unless you use ignoreUnknownElements() as stated by Philipi Willemann)
Of course, if you're the one creating the XML, you should be able to export only the child-2 instance in the first place.

If you know the root name you can create a simple class has an attribute of the class you have mapped to child-2:
#XStreamAlias("root")
class Root {
#XStreamAlias("child-2")
private Child2 child;
//get and set
}
Then when you are processing the XML you can set XStream to ignore unknown elements with xstream.ignoreUnknownElements();

Related

Changing single parameters in XML file wrapped as Java Object

I am getting a config.xml file via a REST API which has a specific structure. I am adapting this config.xml via Java and pushing it again via PUT command to the REST endpoint to update it.
This XML structure contains the same amount of properties (let's say 'name' and 'description') but might be enhanced by some more properties (e.g. 'category'), which I am not aware of.
<config>
<name>myName</name>
<description>myDescription<description>
<category>myCategory<category>
</config>
My goal is to adapt this config file via Java Code while wrapping it into an Object. So I built a Class 'Config' containing 'String name' and 'String description'.
I can easily parse the config.xml to my Config object with JAXB and adapt name and description, but when marshalling it to XML the category would be missing, although it was returned by the REST API. Is there a way (maybe ValueChangeListener?) to adapt only the changed values in an existing xml file?
public class Config { String name; String description; }
So I don't event want to be able to change 'category' at all, I just don't want to lose the data.
Info: In my scenario the Config class is very complex and has alot of subclasses (it's a representing a Jenkins Job). So the example above is very simplified.
I got the idea to create a second config file, only having the changed parameters. Afterwards merging the to config files. But I had no idea how to be aware what exactly has changed and how to implement it.
Example:
I want to change description to "newDescription", so my expected XML would be:
<config>
<name>myName</name>
<description>newDescription<description>
<category>myCategory<category>
</config>
unfortuntately it is:
<config>
<name>myName</name>
<description>newDescription<description>
</config>
Means category parameter is lost, as I am not aware of it and therefore didnt add it to the Config class. Summarized, there might be parameters in the XML file which I am not aware, which I also do not want to change - but don't want to lose when pushing an updated config.

JAXB/MOXy: Mapping elements with unknown names as specific classes

I'm attempting to handle mapping some XML nodes with my existing JAXB/MOXy code and I'm having some trouble determining if what I want to do is even possible.
Essentially, I have some XML data below and although each node has a different name (that I don't know a priori), they have the same structure/content so I'd like to unmarshall them all as instances of the same class; perhaps storing the element name with #XmlPath("#name").
I've looked at using the #XmlAnyElement tag, but I can't work out how to unmarshall as a custom class rather than instances of ElementNSImpl.
Is this even possible with JAXB/MOXy?
<node-group>
<node_a index="1">
<value>Alpha</value>
</node_a>
<node_b index="2">
<value>Beta</value>
</node_b>
<node_c index="3">
<value>Charlie</value>
</node_c>
</node-group>

Multiple config block in java properties file

I need to define multiple configuration blocks in a single .properties file in Spring. Currently I am having multiple .properties file like below:
one.properties:
publishing.channel=ftp
ftp.user=user1
ftp.password=pass1
ftp.host=abc.xyz.com
ftp.port=21
two.properties
publishing.channel=ftp
ftp.user=user2
ftp.password=pass2
ftp.host=def.xyz.com
ftp.port=21
What I now require is defining only one .properties file and add all the configuration blocks in it like so:
publishing.channel=ftp
ftp.user=user1
ftp.password=pass1
ftp.host=abc.xyz.com
ftp.port=21
then another one
publishing.channel=ftp
ftp.user=user2
ftp.password=pass2
ftp.host=cdf.xyz.com
ftp.port=21
it could be http too
publishing.channel=http
http.user=user2
http.password=pass2
http.host=cdf.xyz.com
Problem is when I put multiple property blocks like this, I cannot differentiate in code as my bean methods (e.g. getHost()) will only fetch the last declared one in the properties file. I do not want to create many variables like host1, host2, host3 and so on as it would need to be modified in case there is another block of properties added. How can I make it generic?
Thanks in advance.
You can use PropertiesConfiguration from Apache Commons Configuration and then access all the values of same key and add your logic to get the required value.
Use getStringArray(key) method or getList(key) method to access all values.

Create new child in Dom

I have created test class that created DOM object ,currently I created some attributes
Hard coded ,for example I have create element name structure and for the structure we have attributes,I have created different class that handle the attribute with constructor .
These is the code from the main method
Properties properties = new Properties(document);
Element Property = properties.getProperty();
Properties.setProperty(Property, "product_id","10", "Pro ID");
Type.appendChild(Property);
Properties properties1 = new Properties(document);
Element Property1 = properties1.getProperty();
Properties.setProperty(Property1, "curr","5", "Curr Code");
Type.appendChild(Property1);
The code in the constructor is
public Properties(Document document) {
Property = document.createElement(PROPERTY);
}
As you can see for create new property I have created element property and property1 etc hard coded,which is problematic since what will happen
If I will have table that with list of properties with there data ,how should I handle it?
I am not sure if the constructor is the right solution and my question is how to do that better ?
Thanks!!!
It depends on what you're trying to do.
If you want to create a DOM so that you can test your classes that build DOM's, then simply hard-coding calls will work just fine. You just have to make sure you use enough combinations of calls to thoroughly test you API.
If, on the other hand, you need to create a DOM so that you can then proceed to test your API's that require some sort of DOM input, you might want to consider simply creating those DOM's in the form of XML documents and then using the org.w3c.dom API's to create the DOM from the XML.

Design Pattern Questions in Java

I have a Design pattern Question in Java/J2EE
Problem Statement::
Suppose there are 2 files as below
XYZ.properties file --> name = value pair
abc.xml file --> attribute=value pair.
Both the above files have <name,value> pairs.
The question is "Design a component/jsp page such that you can read,edit,save the name,value pairs of either a Property file or xml file.?"
So which Design pattern would you suggest i should be using in Java.?
The name,values pair are then fetched and displayed in another jsp page where i should be able to read,edit,save the name,value pairs such that
1>read operation results in reading the name,value pair
2>Edit operation results in editing the name,value pair
3>Save operation results in saving the value for the corresponding name,value pair in database and consequently updates either the property/xml file.
**My Initial Analysis** : i would use a Factory design pattern since i have 2 files which have name,value pairs and at run time decide which one to choose depending on the name of file invoked,Once done i would pass the parameters to jsp file for Read,edit and save operation.Save would save the name,value pair to Database but i dont know how will it update the corresponding value for that name in either the property/xml file as well.
Is my Understanding correct ? If not please provide a design/solution in java for the same,such that READ,EDIT,SAVE operation for pairs in either ".properties file" or ".xml file" are carried out?
This looks like homework.
Without giving away too much, Properties can read/write both .properties and .xml files, more info on http://download.oracle.com/javase/7/docs/api/java/util/Properties.html.
The Factory Pattern would do the job.
Create an abstract class with abstract read, modify, save methods and getter and setter for key and value
create two separate classes for .properties and .xml implementation who extend the abstract class.
Whenever you want to save check for the instance of the class and call the appropriate method.
I think Factory pattern is correct. Make abstracted getInstance(fileName), read, create, update, remove methods.
As a suggestion, you might want to return implemented instance after checking into the file content -- whther it's XML (by checking XML header or presence of root tag) or it's a properties file.
Ideally, I would create a MyFileFactory class that looks like this
public class MyFileFactory{
public static final MyFileFactory getInstance(String filename){
//read the file header or first line to guess what instance to call
int fileType = getFileType(fileName);
if(fileType == MyFileFactory.XML_FILE)
return new XMLFileEditor(fileName);
else
return new PropsFileEditor(fileName);
}
public abstract readFile();
public abstract writeToFile();
public abstract editFile();
}
have these classes to implement the methods
public class XMLFileEditor extends MyFileFactory{
...
private File f;
}
and
public class PropsFileEditor extends MyFileFactory{
...
private File f;
}
And I think you are good to go.
If you want to save in database as well as in the file:
writeToFile(String new_Node_or_property){
//parseNode converts the property or XML node to an object
MyNode node = MyNode.parseNode(new_Node_or_property);
MyFileDAO.insert(node);//write a code that parse
// write here code to append in the file based on what
// filetype implentation it is -- XML, .properties, YAML whatever
}

Categories