How to map nested XML fields to CSV? - java

I know how to do this for simple xml like-
<person>
<age>10</age>
<weight>20</weight>
</person>
will be mapped to CSV as-
age,weight
10,20
But how to do it for nested tags?
Example: I have following xml-
<root>
<prop1>someValue</prop>
<prop2>
<innerProp>
<property1>value1</property1>
<property2>
<subProperty1>value2</subProperty1>
<subProperty2>value3</subProperty2>
<subProperty3>value4</subProperty3>
</property2>
<property3>value5</property3>
<property4>value6</property4>
<property5>
<subProperty4>value7</subProperty4>
<subProperty5>value8</subProperty5>
<subProperty6>value9</subProperty6>
</property5>
<property6>value10</property6>
<property7>value11</property>
</innerProp>
</prop2>
</root>
What will be its transformation in CSV?
Or this can't be done at all?

You could flatten this by using a dot for each indent you see. This would be the outcome:
prop1, prop2.innerProp.property1, prop2.innerProp.property2.subProperty1, prop2.innerProp.property2.subProperty2, ...

Related

Process single element array when converting XML to JSON (<?xml-multiple?>)

I'm using org.json.XML.toJSONObject() method to convert an XML string to JSON. Here is a sample XML string that I need to convert.
<?xml version="1.0" encoding="UTF-8"?>
<jsonObject>
<data>
<?xml-multiple accounts?>
<accounts>
<Id>123</Id>
<creationDate>2021-10-21T15:43:00.12345Z</creationDate>
<displayName>account_x</displayName>
</accounts>
</data>
<links>
<self>self</self>
<first>first</first>
<prev>prev</prev>
<next>next</next>
<last>last</last>
</links>
<meta>
<totalRecords>10</totalRecords>
<totalPages>10</totalPages>
</meta>
</jsonObject>
Here, 'accounts' is an element of an array and contains only a single element. But the org.json library cannot detect this. It can detect only if there are multiple elements.
My question is, is there a library that I can use to detect a single element array using the available tag in the XML string?

Creating dynamic XML

Input XML can change, say if the following XML is coming as input:
<Root>
<Fruits></Fruits>
<FruitsName>
<Apple></Apple>
<Mango></Mango>
</FruitsName>
</Root>
than output should be generated based on a mapping file.
Here say Fruits to be mapped with F1.
FruitsName to be mapped with FN.
Apple to be mapped with App.
Mango to be mapped with Man which will be present in properties file.
Output:
<Root>
<F1> </F1>
<FN>
<App></App>
<Man></Man>
</FN>
</Root>
Now if the input XML has different tags than XML should be generated based on
the mapping file/properties file.
You are doing an XML to XMl transformation.
You can Make use of XSLT to achieve the output.
Thanks!
You can achieve using following simple dataweave script:
%dw 1.0
%output application/xml
---
{
Root:{
F1: payload.Root.Fruits,
FN:{
App: payload.Root.FruitsName.Apple,
Man: payload.Root.FruitsName.Mango
}
}
}
output as you expect:
<?xml version='1.0' encoding='windows-1252'?>
<Root>
<F1></F1>
<FN>
<App></App>
<Man></Man>
</FN>
</Root>

Camel aggregation of XMLs based on the value of XML elements

I have the following XMLs:
XML1:
<Person>
<Name>Ben</Name>
<Adress>1234</Address>
</Person>
XML2:
<Person>
<Name>Johnson</Name>
<Adress>5678</Address>
</Person>
XML3:
<Person>
<Name>Harry</Name>
<Adress>1234</Address>
</Person>
I want to aggregate the XMLs only if the attribute value of the Address element is the same, so in this case XML1 and XML3 will be aggregated to look like:
<Person>
<Name>Ben</Name>
<Adress>1234</Address>
</Person>
<Person>
<Name>Harry</Name>
<Adress>1234</Address>
</Person>
(P.S: Result need not be an XML, can be a string).
Is it possible using Camel ?
from ("direct:x")
..............
.to(output)
This is the approach I will take, In fact I have done it already.
Use a simple processor to aggregate all these XML's to a single XML
Write a XSLT to create your desired XML from the aggregated XML, that way if at all you want to change your logic, you can just do it inside XSLT. XSLT is powerful this way.
I would hesitate to either keep these kind of logic in camel routes or write a pojo to do the job.

How to add multiple attribute values to xml file in JAVA using DOM

I have One XML Like
<root>
<name id="1">Abc</name>
<salary>25000</salary>
</root>
I want something like this
<root>
<name id="1,2">Abc</name>
<salary>25000</salary>
</root>
I am able to create the attribute by using DOM parser as:
Document doc = _docBuilder.newDocument();`
Attr attr = doc.createAttribute("id");
attr.setValue("1");
name.setAttributeNode(attr);
How can I get multiple attribute values for the same attribute.
XML does not support attributes with multiple values.
You could certainly do: attr.setValue("1,2");
However that really isn't very XML friendly. Also, you probably shouldn't have more than one value for an id. You may wish to consider something like this:
<thing>
<name>Abc</name>
<reference_ids>
<id>1</id>
<id>2</id>
</reference_ids>
</thing>

DOM parser for non xml

i want to parse the following type of text. Example1
<root>my name is <j> <b> mike</b> </j> </root>
example 2
<root> my name is <mytag1 attribute="val" >mike</mytag1> and yours is <mytag2> john</mytag2> </root>
can i parse it using a DOM parser?I will not have the same format evry time .I can have different formats in which the tags are nested.I dont know the format in advance.
Both these examples are valid XML documents so there's no reason you can;t do this.
If your XML is very simple, especially if it combines text and tags together, you may want to run it via an XSL transformation first, to have a format easier to parse or to convert it to other format, such as HTML.
You can use a DOM parser for the examples you've given - they're valid XML. However, you wouldn't be able to use it for non-XML as per your subject line.
When you say you can have "different formats in which the tags are nested" what exactly do you mean? If it's always simple nesting, e.g.
<root>
<tag1>
<tag2>
<tag3>
Stuff
</tag3>
</tag2>
</tag1>
</root>
Then that will be fine. However, an XML parser won't like markup where an "outer" tag is closed before an "inner" one:
<root>
<tag1>
<tag2>
Stuff
</tag1> <!-- Invalid -->
</tag2>
</root>

Categories

Resources