Merge two xml strings in java - java

I'm trying to merge/combine two xml strings that I got from parsing an object to XML using castor marshalling/unmarshalling. Here are the two XML strings that I have:
<?xml version="1.0" encoding="UTF-8"?>
<abc:abcResponse xmlns:abc="http://www.abc.com/schema/abcTransaction">
<abc:code>0</abc:code>
<abc:description>blah</abc:description>
</abc:abcResponse>
<?xml version="1.0" encoding="UTF-8"?>
<abc:abcRequest xmlns:abc="http://www.abc.com/schema/abcTransaction">
<abc:id>99999</abc:id>
<abc:idString>abc</abc:idString>
</abc:abcRequest>
I want to be able to combine these two strings into one so I can insert this into my database (MSSQL) column that has data type XML. I tried using the solution suggested from this link java merge two xml strings in java, but it doesn't seem to recognize it as a valid XML string since no records were inserted into the database table, and there's this error in my console:
com.microsoft.sqlserver.jdbc.SQLServerException: XML parsing: line 1, character 12, text/xmldecl not at the beginning of input
If I insert either of these strings separately into the database column then a new record will be added just fine.
Anyone has a good idea as to how to do this properly? Much thanks!

You should create something like the following ("abcTransaction" is a wild guess).
<?xml version="1.0" encoding="UTF-8"?>
<abc:abcTransaction xmlns:abc="http://www.abc.com/schema/abcTransaction">
<abc:abcRequest>
<abc:id>99999</abc:id>
<abc:idString>abc</abc:idString>
</abc:abcRequest>
<abc:abcResponse>
<abc:code>0</abc:code>
<abc:description>blah</abc:description>
</abc:abcResponse>
</abc:abcTransaction>
Maybe even leaving out the xmlns and "abc:" parts.

Related

What is difference between "com.sun.xml.bind.xmlDeclaration=false" and "jaxb.fragment=true"?

Recently when i worked with JAXB i had to remove xml header from generated file. I mean, i had to remove first line in xml file which looks like in this way:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
After few minutes i found on internet, that i can use one of this solution:
marshaller.setProperty("jaxb.fragment", true);
or
marshaller.setProperty("com.sun.xml.bind.xmlDeclaration", false);
Both worked for me... but what is difference between them?
NOTE: I'm using Java 12
I created a MCVE which can be found here https://github.com/starwarsjk/jaxb-remove-xml-header
"com.sun.xml.bind.xmlDeclaration" is from JAXB 1 but still supported in JAXB 2.
Marshaller.JAXB_FRAGMENT is equivalent but preferred going forward.

How to change xml element name when marshalling in java

I am trying to create xml file using java. where the expected output is given below
EXPECTED OUTPUT
<?xml version="1.0" encoding="utf-8"?>
<Invoice xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2"
xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2"
xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2">
<cbc:CustomizationID>urn:cen.eu:en16931:2017#compliant#urn:fdc:peppol.eu:2017:poacc:billing:3.0</cbc:CustomizationID>
<cbc:ProfileID>urn:fdc:peppol.eu:2017:poacc:billing:01:1.0</cbc:ProfileID>
<cbc:ID>2019-112</cbc:ID>
<cbc:IssueDate>2019-01-21</cbc:IssueDate>
<cbc:InvoiceTypeCode>380</cbc:InvoiceTypeCode>
</Invoice>
ACTUAL OUTPUT
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns4:Invoice xmlns="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2" xmlns:ns2="urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2" xmlns:ns3="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2" xmlns:ns4="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2">
<CustomizationID>urn:cen.eu:en16931:2017#compliant#urn:fdc:peppol.eu:2017:poacc:billing:3.0</CustomizationID>
<ProfileID>urn:fdc:peppol.eu:2017:poacc:billing:01:1.0</ProfileID>
<InvoiceTypeCode>380</InvoiceTypeCode>
</ns4:Invoice>
For clear understanding, lets take "cbc:CustomizationID" in expected output, but in actual output only "CustomizationID"
The actual output is the same as the expected. Just changes how the namespaces are applied.
The XML Parser should treat it exactly the same.
Take a look at XML namespaces.
I have changed the #XmlElement(name = "cbc:CustomizationID", required = true) after generating java class using xjc command. partially issue is solved but needs to change root element to inserted of

Add record="RECORD_FROM_RINGING" attribute to TwilioML XML using Java in ColdFusion

We are using ColdFusion and Java to generate the Twilio Markup / XML necessary for handling Twilio calls in our webhook.
Currently, everything works well. The output xml/twiml generated looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Dial callerId="+18184461999">
<Number>+18554904999</Number>
</Dial>
</Response>
We generated this markup using java classes in ColdFusion, mainly because ColdFusion can't do it natively. This is the ColdFusion/Java code we currently use to generate the above xml:
<cfscript>
TWILIO_CALLER_ID = "+18184461999";
tophn="+18554904999";
objPattern = CreateObject("java","java.util.regex.Pattern").Compile(JavaCast( "string", "^[\\d\\+\\-\\(\\) ]+$"));
objMatcher=objPattern.Matcher(JavaCast( "string", tophn ));
dialBuilder = createObject("java","com.twilio.twiml.Dial$Builder").init();
dialBuilder.callerId(TWILIO_CALLER_ID);
numberbuilder= createObject("java","com.twilio.twiml.Number$Builder").init(tophn).build();
dialBuilder = dialBuilder.number(numberbuilder);
voiceTwimlResponse = createObject("java","com.twilio.twiml.VoiceResponse$Builder").dial(dialBuilder.build()).build();
response = '<?xml version="1.0" encoding="UTF-8"?>' & voiceTwimlResponse.toXml();
</cfscript>
Everything above works perfectly for our needs.
However, now we would like to add an attribute to the "Dial" element: record="RECORD_FROM_RINGING". Below is what the XML we would like generated would look like:
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Dial callerId="+18184461999" record="RECORD_FROM_RINGING">
<Number>+18554904999</Number>
</Dial>
</Response>
How would we use ColdFusion + java to accomplish this? We have spent hours trying to figure this out, and nothing works for us. We have looked into the Record and Record$Builder classes, but found nothing that adds this attribute the way we need it. The closest we got to was being able to add a <Record /> element before the <Dial> element, but that does not work for us.
How do we add the attribute record="RECORD_FROM_RINGING" to the <Dial> element using ColdFusion and the appropriate Java classes/objects? All we require is the attribute to be set for that element.
My guess is you are using an older version of the jar which does not support all of the <Dial> attributes. Looks like the Twilio instructions link to an older version (currently 7.0.0). The GitHub version is already up to 7.8.0. Try downloading 7.8.0 or building a newer version from the source (do not forget the dependencies).
The Dial.Builder class in 7.8.0 contains a new method named options(String key, String value) which supports arbitrary attributes. Use it to set the "record" attribute like this:
...
recordOption = createObject("java","com.twilio.twiml.Dial$Record");
dialBuilder.options("record", recordOption.RECORD_FROM_RINGING.toString());
...
** Using the Dial.Record enum, instead of a hard coded string, helps insulate the code against changes in the API.
Result:
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Dial callerId="+18185551999" record="record-from-ringing">
<Number>+18185554999</Number>
</Dial>
</Response>

Problems using commons digester to parse subversion XML output

The Subversion XML formatted output is a combination of attribute and elements - particularly within the <path> element - see the sample below:
<?xml version="1.0" encoding="UTF-8"?>
<log>
<logentry
revision="29">
<author>bob</author>
<date>2013-02-14T17:21:42.848605Z</date>
<paths>
<path
action="A"
kind="dir"
copyfrom-path="/trunk"
copyfrom-rev="28">/tags/TAG-0.1</path>
</paths>
<msg>Creating tag TAG-0.1</msg>
</logentry>
</log>
I'm trying to use commons digester to parse this the log content into two different POJO's (LogEntry and Path) using the following:
ArrayList<LogEntry> logEntries = new ArrayList<LogEntry>();
digester.push(logEntries);
digester.addObjectCreate("*/logentry", LogEntry.class);
digester.addSetProperties("*/logentry");
digester.addBeanPropertySetter("*/logentry/author");
digester.addBeanPropertySetter("*/logentry/date");
digester.addBeanPropertySetter("*/logentry/msg");
digester.addSetNext("*/logentry", "add");
digester.addObjectCreate("*/logentry/paths/path", Path.class);
digester.addSetProperties("*/logentry/paths/path");
digester.addBeanPropertySetter("*/logentry/paths/path", "value");
digester.addSetNext("*/logentry/paths/path", "addPath");
(note addPath adds the path object being created onto an ArrayList<Path> within the created LogEntry object)
I can't figure out why the Path class is not being fully populated. Based upon the XML I can understand why the copyfrom-rev and copyfrom-path attributes might not be getting copied (due to the hyphen) into the corresponding copyFromRev attributes.
But I can't see any reason why the kind attribute isn't being set within the Path.
Does anyone have any ideas?
I need to use a digester.addSetProperties() call to get the copyfrom-path and copyfrom-rev attributes populated:
digester.addSetProperties("*/logentry/paths/path", "copyfrom-path", "copyfrompath");
digester.addSetProperties("*/logentry/paths/path", "copyfrom-rev", "copyfromrev");
However for some reason the kind attribute still isn't being populated.

extracting attribute value in XML using regex

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!DOCTYPE ... ]>
<abc-config version="THIS" id="abc">
...
</abc-config>
Hi all,
In the code above, how can I extract the value of version attribute using Regex in Groovy/Java?
Thanks.
A regex to handle this could be something like:
/<\?xml version="([0-9.]+)"/
I'll spare you one of the 10000 lectures about not using a regex to parse markup languages.
Edit: The One whose Name cannot be expressed in the Basic Multilingual Plane, He compelled me.
I know you asked for a regex, but what's wrong with this in Groovy?
Assuming the xml is something like:
def xml= '''<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!DOCTYPE abc-config>
<abc-config version="THIS" id="abc">
<node></node>
</abc-config>'''
Then I can parse it with:
def n = new XmlSlurper().parseText( xml )
And then this line:
println n.#version
Prints out "THIS"
If you are having problems with a more complex DOCTYPE failing to load, you can try disabling the DOCTYPE checker by either:
def parser = new XmlSlurper()
parser.setFeature( "http://apache.org/xml/features/nonvalidating/load-external-dtd", false )
parser.setFeature( "http://xml.org/sax/features/namespaces", false )
parser.parseText( xml )
or by using the constructor for XmlSlurper that takes 2 parameters so as to disable this checking
Not a java regex, Perl regex...
/<\w+\s+[^>]*?(?<=\s)version\s*=\s*["'](.+?)["'][^>]*?\s*\/?>/sg
Note that this fails on many levels, I could fill the page with a proper regex, but I don't have the desire.
this fails too ...
/<\w+\s+[^>]*?(?<=\s)version\s*=\s*(".+?"|'.+?')[^>]*?\s*\/?>/sg
so does this
/<\w+\s+[^>]*?(?<=\s)version\s*=\s*(["'])(.+?)\1[^>]*?\s*\/?>/sg

Categories

Resources