How to convert attributes to nodes of an xml in java? - java

I am parsing an XML file like
<STRUCTURE ID="EV_Se96ffb9a-df1f-44e7-a4f8-818688cf8d3b">
<SHORT-NAME>STRUCT</SHORT-NAME>
<LONG-NAME>Structure</LONG-NAME>
</STRUCTURE>
where I am getting the child nodes of STRUCTURE and adding it to a nodeList.
Can I have an option to add the attributes of STRUCTURE i.e, ID to a nodeList ?
How to convert the attributes to a node and add it to a nodelist ?
Please help me out.
I am using the DOM parsing strategy

The Node class has a method getAttributes() which returns a NamedNodeMap. Of course, only elements will return an appropriate named node map (as only elements can have attributes).
On such a NamedNodeMap you can then retrieve the attribute node via a call to getNamedItem(String) or via a call to item(int). Note, that the return type of these methods is a Node, which - in case of attributes - will in fact be an Attr.

Related

Java Method create datapoint node in the container of XML

how to fetch elements of container from XSD by XPath.

Make content node primary parent of node

I try to use the Alfresco NodeService to make a content node (QName cm:content) the primary parent of another content node. NodeService provides a method
public ChildAssociationRef moveNode(
NodeRef nodeToMoveRef,
NodeRef newParentRef,
QName assocTypeQName,
QName assocQName)
throws InvalidNodeRefException;
Let's say the current primary parent of the node theNodeToMove is a folder and the primary parent assoc reference of the node in the folder is primaryAssocRef. Let theTargetContentNode be the target content node.
Calling the above message like this
nodeService.moveNode(theNodeToMove,
theTargetContentNode,
primaryAssocRef.getTypeQName(),
primaryAssocRef.getQName());
fails. Alfresco reporst an integrity violation:
The association source type is incorrect:
Source Node: workspace://SpacesStore/27a97736-222c-4bac-8610-f15ce312b074
Association: Association[ class=ClassDef[name={http://www.alfresco.org/model/content/1.0}folder], name={http://www.alfresco.org/model/content/1.0}contains, target class={http://www.alfresco.org/model/system/1.0}base, source role=null, target role=null]
Required Source Type: {http://www.alfresco.org/model/content/1.0}folder
Actual Source Type: {http://www.alfresco.org/model/content/1.0}content
Is it even possible to make a content node the primary parent of an existing content node?
Yes and no. Yes because content node can have children, and no because you can't use the "contains" association.
Basically, when you create a "parent-child" relation, you need to state it's association type. You can have as many of these, for instance rm:rendition is one of these types.
The "main" association type used when you create a document under a folder is cm:contains, and is setup in a way that does not allow content nodes to have children. This is done through model definition, and looks something like this:
<type name="cm:folder">
<title>Folder</title>
<parent>cm:cmobject</parent>
<archive>true</archive>
<associations>
<child-association name="cm:contains">
<source>
<mandatory>false</mandatory>
<many>true</many>
</source>
<target>
<class>sys:base</class>
<mandatory>false</mandatory>
<many>true</many>
</target>
<duplicate>false</duplicate>
<propagateTimestamps>true</propagateTimestamps>
</child-association>
</associations>
</type>

Java spring XML binding based on conditions using JAXB

I am binding XML to object using JAXB, is it possible to bind based on conditions such as
Bind href attribute in api:page element where attribute position is equal to next.
Or get all records as standard list and then filter out by using if condition
<api:pagination results-count="93" items-per-page="25">
<api:page position="this" href="https://url1.com" />
<api:page position="next" href="https://url1.com?pid=2" />
</api:pagination>
It is not necessary to make a transformation for such a simple setup.Take advantage of #XmlAnyElement https://docs.oracle.com/javase/8/docs/api/javax/xml/bind/annotation/XmlAnyElement.html and just map your collection as a list of Elements.
#XmlElementWrapper(name = "pagination")
#XmlAnyElement
public List<Element> getPages() {
return pages;
}
Where Element is org.w3c.dom.Element
The #XmlElementWrapper is optional, if you want you can map your pagination element. I am not sure you need it though.
Then you extract the position with:
page.getAttribute("position")
and
page.getAttribute("href")
for the url

#XMLRootElement element or array name

I am currently trying to unmarshall a xml get response into one intricate java object. That java object has other classes as fields, so it goes very deep. Now, I am using the JaxbMarshaller2 for this job. So far everything has been going well, but now I am have a question:
Basically one of the tags in the XML stream is called "images" and contains an array of individual image items, each enclosed in the "item" tag.
<images>
<item>
<name></name>
</item>
<item>
<name></name>
</item>
</images>
Now, in my root java class, I have a property called images, which is a list of these image items (I made a custom class for these items.)
#XmlElement(name = "images")
private List<ProductImage> images;
Ok, now inside the ProductImage class, would the XML root element above the class name be #XmlRootElement(name="images") or #XmlRootElement(name="item")?
Thanks for your responses.
The #XmlRootElement annotation is only necessary for the root element of your xml file. Each parent always defines the names of the tags of its children. But since the root element has no parent, there is an additional annotation necessary to define its name (i.e. #XmlRootElement).
Option1:
Assuming that the <images> node is your root node of your xml file.
Create a class ProductImageCollection which has the #XmlRootElement(name="images") annotation.
Inside this class there should be a List<ProductImage> which has an annotation #XmlElement(name="image")
Option2:
Assuming that your <images> node is part of a bigger xml structure, which already has correct annotations.
Then you don't need any additional #XmlRootElement annotations. You can directly annotate your list with #XmlElementWrapper(name="images").

Question on XML parsing

When I am parsing an xml string as below I get strange attributes like "autowire" with value "default". Is there anyway I can get only the attributes that are explicitly defined?
<bean id="aaaa" class="com.test.Service">
<property name="cccc" ref="cccc"/>
</bean>
I am doing simple parsing turning it into a Document and then iterating over the Nodes.
Document document = docBuilder.parse(input);
NodeList nodeList = document.getChildNodes();
etc.
You can use following APIs to find whether an attribute is explicitly specified or not:
if you are using DOM:
Attr.getSpecified()
if you are using SAX:
Attributes2.isSpecified(qname)
It depends what you are using to parse. I'm guessing this is a Spring bean configuration file. Usually there's a XML Schema associated with it and that will dictate all default values for attributes.
So when the actual XML parser walks through the document, it will build some kind of representation (DOM parsers will obviously build a tree, SAX parsers will fire off events, etc) of the XML and insert those default values.

Categories