Construct variable HashMap object from XML template - java

I receive from Webservice the following XML:
<ns1:irsValorationReturn xmlns:ns1="http://webServices.es">
<ns1:error xsi:nil="true"/>
<ns1:format>dd/MM/yyyy</ns1:format>
<ns1:pricingDate>02/09/2013</ns1:pricingDate>
<ns1:results>
<ns1:items>
<ns1:bpv>-395.79435433174876</ns1:bpv>
<ns1:npv>26960.051401523993</ns1:npv>
<ns1:payingNpv>0.0</ns1:payingNpv>
<ns1:pricingDelta>342.85778485967523</ns1:pricingDelta>
<ns1:receivingNpv>26960.051401523993</ns1:receivingNpv>
<ns1:swapRate>0.6811631117640043</ns1:swapRate>
</ns1:items>
</ns1:results>
</ns1:irsValorationReturn>
I need to transform this XML into a HashMap. The entries of HashMap must be variables depending on the value between keys {} ({KEY OF HASHMAP}) from the template below. The value of the corresponding key in Hashmap would be the original value from the WebService XML response, i.e.
BPV = -395.79435433174876;
NPV = 26960.051401523993
...
<ns1:irsValorationReturn xmlns:ns1="http://webServices.es">
<ns1:error xsi:nil="true"/>
<ns1:format></ns1:format>
<ns1:pricingDate><ns1:pricingDate>
<ns1:results>
<ns1:items>
<ns1:bpv>{BPV}</ns1:bpv>
<ns1:npv>{NPV}</ns1:npv>
<ns1:payingNpv>{PAYING_NPV}</ns1:payingNpv>
<ns1:pricingDelta>{PRICING_DELTA}</ns1:pricingDelta>
<ns1:receivingNpv>{RECEIVING_NPV}</ns1:receivingNpv>
<ns1:swapRate>{SWAP_RATE}</ns1:swapRate>
</ns1:items>
</ns1:results>
</ns1:irsValorationReturn>
If I change {NPV} for {NPV_NEW} the resulting HashMap should be:
BPV = -395.79435433174876;
NPV_NEW = 26960.051401523993
I thought in parse template XML and when you find a tag with a value that matches with pattern {.+} search through the original XML for that tag. Then you put the entry in Hashmap with the key of the template XML and the value of the original XML.
Has any better way? I think it can be a little inefficient parsing original XML each time I find a node with variable value.

Did you check XStream?
Also this might be a duplicate of How to convert XML to java.util.Map and vice versa where they also talk about XStream.
Unless you have a huge XML reply I think XStream will be fast enough for parsing, and probably faster than parsing the XML yourself (This is however a guess since I don't know if you come up with a really clever way. :)).

Related

How to stop Jackson from parsing an element?

I have a XML Document where there are nested tags that should not be interpreted as XML tags
For example something like this
<something>cbaabc</something> should be parsed as a plain String "cbaabc" (it should be mentioned that the document has other elements as well that get parsed just fine). Jackson tho tries to interpret it as an Object and I don't know how to prevent this. I tried using #JacksonXmlText, turning off wrapping and a custom Deserializer, but I didn't get it to work.
The <a should be translated to <a. This back and forth conversion normally happens with every XML API, setting and getting text will use those entities &...;.
An other option is to use an additional CDATA section: <![CDATA[ ... ]]>.
<something><![CDATA[cbaabc]]></something>
If you cannot correct that, and have to live with an already corrupted XML text, you must do your own hack:
Load the wrong XML in a String
Repair the XML
Pass the XML string to jackson
Repairing:
String xml = ...
xml = xml.replaceAll("<(/?a\\b[^>]*)>", "<$1>"); // Links
StringReader in = new StringReader(xml);

How to parse xml with java

I'm calling a soap webservice from my java application.
I get response and I want to parse it and get data.
The problem is that field <tranData>, contains structure with >< instead of <>. How can I parse this document to get data from field <tranData>?
This is response structure:
<response>
<Portfolio>
<ID>1</ID>
<holder>2</holder>
</Portfolio>
<tranData> <responseOne><header><code>1</code></header></responseOne></tranData>
Please remember that, this is only a example of response, and the amount of data will be much bigger, so the solution should be fast.
What you show us is the actual document as it is received over the wire, right? So <tranData> contains an XML string that has been escaped to not interfere with the markup of the rest of the containing document.
When you read the content of the <tranData> element, the XML processor will 'unescape' the string and give you the 'original' value:
<responseOne><header><code>1</code></header></responseOne>
What you do with that value is a different story. You can parse it as yet another XML document and retrieve the value of the <code> element, or just pass the string along to some other processing step.

How to convert nested tags in dynamic XML into a for loop?

I want to convert dynamic xml file into a specific file format. i could able to parse the xml using jsoup parser but the problem is I want to parse the nested tags and put it into a for-loop.Is there any way to do it. Attaching the sample below for reference
Input XML(sample)
<lineComponents>
<invoiceComponents>
<invoiceComponent>
<type></type>
<name></name>
<amount>16.00</amount>
<taxPercentage>0.00</taxPercentage>
<taxAmount>0E-8</taxAmount>
</invoiceComponent>
</invoiceComponents>
<acctComponents>
<acctComponent>
<componentCode>BASE</componentCode>
<glAccountNr></glAccountNr>
<baseAmount>10.00000</baseAmount>
<taxRate>0.00</taxRate>
<taxAmount>0.00000</taxAmount>
<totalAmount>10.00000</totalAmount>
<isVAT>No</isVAT>
</acctComponent>
<acctComponent>
<componentCode></componentCode>
<glAccountNr></glAccountNr>
<baseAmount>3.00000</baseAmount>
<taxRate>0.00</taxRate>
<taxAmount>0.00000</taxAmount>
<totalAmount>3.00000</totalAmount>
<isVAT>No</isVAT>
</acctComponent>
<acctComponent>
<componentCode>DISC</componentCode>
<glAccountNr></glAccountNr>
<baseAmount>-2.00000</baseAmount>
<taxRate>0.00</taxRate>
<taxAmount>0.00000</taxAmount>
<totalAmount>-2.00000</totalAmount>
<isVAT>No</isVAT>
</acctComponent>
<acctComponent>
<componentCode>ARPIT</componentCode>
<glAccountNr></glAccountNr>
<baseAmount>5.00000</baseAmount>
<taxRate>0.00</taxRate>
<taxAmount>0.00000</taxAmount>
<totalAmount>5.00000</totalAmount>
<isVAT>No</isVAT>
</acctComponent>
</acctComponents>
</lineComponents>
Expected output:
for(OrderItem invoiceLineItem: orderLineWrp.invoiceLineItems){
Dom.XMLNode invoiceComponentNode = invoiceComponentsNode.addChildElement(EP_OrderConstant.invoiceComponent,null,null);
invoiceComponentNode.addChildElement(EP_OrderConstant.seqId,null,null).addTextNode(getValueforNode(invoiceLineItem.EP_SeqId__c));
invoiceComponentNode.addChildElement(EP_OrderConstant.TYPE,null,null).addTextNode(getValueforNode(invoiceLineItem.EP_ChargeType__c));
invoiceComponentNode.addChildElement(EP_OrderConstant.name,null,null).addTextNode(getValueforNode(invoiceLineItem.EP_Invoice_Name__c));
invoiceComponentNode.addChildElement(EP_OrderConstant.amount,null,null).addTextNode(getValueforNode(invoiceLineItem.UnitPrice)); //Value for amount
invoiceComponentNode.addChildElement(EP_OrderConstant.taxPercentage,null,null).addTextNode(getValueforNode(invoiceLineItem.EP_Tax_Percentage__c)); //Value for taxPercentage
invoiceComponentNode.addChildElement(EP_OrderConstant.taxAmount,null,null).addTextNode(getValueforNode(invoiceLineItem.EP_Tax_Amount_XML__c)); //Value for taxAmount
}
This Xml file is dynamic. Is there any way to handle dynamic XML file into a specific format like above?
Jsoup is rather for HTML parsing.
If you have XSD/DTD to your XML, you should use JAXB-generated classes and an unmarshaller to read it.
Otherwise you can use JAXP (DOMParser, if the file is small, and XPath, or event based SAXParser(however this is not so easy to use) for really large XML files).

Validate XML against a catalog of values in other xml

I have a XML file with the following content:
<example>
<firstNode>
<someInfo>Hello</someInfo>
</firstNode>
<secondNode>
<myFlagColors>
<using>RED</using>
<using>WHITE</using>
<using>BLUE</using>
</myFlagColors>
</secondNode>
</example>
I have to check that every node <using>XYZ</using> has a value (like XYZ) coming from another XML like this one:
<colorCatalog>
<color>WHITE</color>
<color>BLACK</color>
<color>RED</color>
<color>GREEN</color>
<color>BLUE</color>
<color>YELLOW</color>
<color>PINK</color>
<color>ORANGE</color>
<color>CYAN</color>
</colorCatalog>
I donĀ“t like my current implementation made with java:
Convert every XML in a java Bean (using jaxb) and then use an iterator
to check if the value in the first bean in in the array of values of the second object.
My question: Is it possible to do this just by using xsd files? or any other way simpler than pure programming?
XML Schema Approach
If you can combine the XML documents then you could create an XSD that has a keyRef relationship between the 2 elements.
Validating the document against the schema would then highlight any errors.
If you can't combine the XML files easily then you could use xinclude (as long as your XSD parser supports it). Xerces for example supports it.

Invalid character while converting from JSON to XML using jsonlib

I'm trying to convert a JSON string to XML using jsonlib in Java.
JSONObject json = JSONObject.fromObject(jsonString);
XMLSerializer serializer = new XMLSerializer();
String xml = serializer.write( json );
System.out.println(xml);
The error that I get is
nu.xom.IllegalNameException: 0x24 is not a legal NCName character
The problem here is that I have some properties in my JSON that are invalid XML characters. eg. I have a property named "$t". The XMLSerializer throws the exception while trying to create a XML tag in this name because $ is not allowed in XML tag names. Is there any way in which I can override this XML well formedness check done by the serializer?
First I'd suggest to add the language you are using (it is Java, right?).
You could override the method where it checks your XML tag name to do nothing.
I took a look at the spec for the json-lib XMLSerializer and to my surprise it seems to have no option for serialising a JSON object whose keys are not valid XML names. If that's the case then I think you will need to find a different library.
You could loop over json.keySet (recursively if necessary) and replace invalid keys with valid ones (using remove and add).

Categories

Resources