I want to parse the following xml snippet. Can anyone help me out in this. I am not getting how to parse through the elements and all and just retrieve the and EmployeeId nodes and its values
<soapenv:Envelope xmlns:soapenv="http://schemas.xxx/yyy" xmlns:idi="http://xxxx/">
<soapenv:Header/>
<soapenv:Body>
<idi:retrieve>
<requestXML>
<CustomerNumber>111</CustomerNumber>
<EmployeeId>222</EmployeeId>
</requestXML>
</idi:retrieve>
</soapenv:Body>
</soapenv:Envelope>
Please see the xml above and give some hinte to parse this.
Thank you
You should use a framework that knows to create an object model from a WSDL and do the parsing for you - that is the best course of action.
Just google on any of these:
Axis2
JAX-WS
JAX-RPC
Choose one and use it.
Related
I want to know how I can generate the following using JAXB.
Main problem - having two namespaces in soapenv. When I make the xml and then add the soap env, it adds name spaces in different lines. This is not the way I want it
Problem 2 - instead of xmlsn="..." I want xmlns:SOME_TEXT="..." as shown below
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:fis="http://fis.certegy.cka.com/">
<soapenv:Body>
<fis:InquiryRequest>
<Version>1.0</Version>
<RequestUID>191919191919191</RequestUID>
<Station>1078686704</Station>
<TranType>40</TranType>
<Consumer>
<FirstName>Susie</FirstName>
<LastName>Smith</LastName>
<Address>
<Line1>100 59th</Line1>
<Line2>Ave NE</Line2>
<City>New York</City>
<State>NY</State>
<Zip>10021</Zip>
</Address>
<Phone>1114589658</Phone>
<EmailAddress>Your.Email#yahoo.com</EmailAddress>
<DateOfBirth>1960-01-01</DateOfBirth>
<ID>
<Type>NY</Type>
<Value>285756967</Value>
</ID>
<DeviceID>12345678000</DeviceID>
<DaysOfEmployment>9991</DaysOfEmployment>
<PayDate>2019-05-03</PayDate>
<PayFrequency>Weekly</PayFrequency>
</Consumer>
<Amount>70.00</Amount>
<CashBack>0</CashBack>
<GiftCard>0</GiftCard>
<Check>
<Micr>
<ExpansionType>1002</ExpansionType>
<Line>T861000016A100002106C</Line>
<Swiped>false</Swiped>
</Micr>
<Type>P</Type>
</Check>
</fis:InquiryRequest>
</soapenv:Body>
</soapenv:Envelope>
Please note: I am using the EclipseLink MOXY which is an extension of the JAXB and provides a lot of additional benefits compared to normal JAXB. The below answer is based on the MOXY not sure if it would work even for Standard JAXB.
I am not sure if I have understood your problem 1 correctly. Based on my understanding when you solve the problem-2 then I am guessing it should solve this as well. As it will add all the namespaces to the header of the XML in your case soapenv:Envelope.
With regards to your problem 2:
If you would like to obtain the custom prefix for your namespace URI then you can create a Map<String, String> with your prefix and namespace and pass it during the marshaling so the moxy would automatically handle and provide the prefix to header (xmlns) and your XML node.
Map<String, String> namespaces = new HashMap<String, String>();
namespaces.put("http://schemas.xmlsoap.org/soap/envelope/", "soapenv");
namespaces.put("http://fis.certegy.cka.com/", "fis");
namespaces.put("Whatever your namespace", "SOME_TEXT");
jsonMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
jsonMarshaller.setProperty(MarshallerProperties.NAMESPACE_PREFIX_MAPPER, namespaces);
jsonUnmarshaller.setProperty(UnmarshallerProperties.JSON_NAMESPACE_PREFIX_MAPPER, namespaces);
Reference documentation
GitHub code
I am not a expert on Java but looking for help on issue we are seeing. With our java Jackson response , we are trying to build a XML based response but response is coming without a namespace prefix like below
Kindly help
<EmployeeResponse **xmlns**="http://test.service.net/com/v1">
<Reference>SequenceTime="2019-03-07 12.15.01.970236"</Reference>
<Details>
<Name>
<FirstName>Alex</FirstName>
</Name>
</Details>
</EmployeeResponse>
However we would like to have the response defined as a space prefix like below where v1 would denote a namespace type and same should be mapped to all child elemetns.
<v1:EmployeeResponse xmlns:v1="http://test.service.net/com/v1">
<v1:Reference>SequenceTime="2019-03-07 12.15.01.970236"</v1:Reference>
<v1:Details>
<v1:Name>
<v1:FirstName>Alex</v1:FirstName>
</v1:Name>
</v1:Details>
</v1:EmployeeResponse>
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>
I am trying to parse below xml using saxparse in java code but i get SAXParseException. xml looks fine. Not sure why i get this exception. Can anyone help me know what is the problem with my xml. Thanks in advance!
<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope" xmlns:m0="http://schemas.compassplus.com/two/1.0/fimi_types.xsd" xmlns:m1="http://schemas.compassplus.com/two/1.0/fimi.xsd">
<env:Body>
<m1:UserDefinedRp>
<m1:Response Response="1" TranId="7643629" Ver="14.3" Product="XXX"/>
</m1:UserDefinedRp>
</env:Body>
</env:Envelope>
Below is the exception i get:
org.xml.sax.SAXParseException: Element type "env:Envelope" must be followed by either attribute specifications, ">" or "/>".
at org.apache.xerces.framework.XMLParser.reportError(XMLParser.java:1213)
at org.apache.xerces.framework.XMLDocumentScanner.reportFatalXMLError(XMLDocumentScanner.java:579)
at org.apache.xerces.framework.XMLDocumentScanner.abortMarkup(XMLDocumentScanner.java:628)
at org.apache.xerces.framework.XMLDocumentScanner.scanElement(XMLDocumentScanner.java:1800)
at org.apache.xerces.framework.XMLDocumentScanner$ContentDispatcher.dispatch(XMLDocumentScanner.java:949)
at org.apache.xerces.framework.XMLDocumentScanner.parseSome(XMLDocumentScanner.java:381)
at org.apache.xerces.framework.XMLParser.parse(XMLParser.java:1098)
If you think it is correct XML (yes, it looks fine) try to check nonprintable chars, sometimes IDE or other editors add them. Try to check it.
I am trying to call a DotNet based SOAP Webservice from my Java client and the SOAP request XML contains a CDATA xml as the value in <ser:answerFile> tag. The ideal SOAP request would look something like the below:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://services.intel.com/">
<soapenv:Header>
<ser:SessionHeader>
<ser:SessionId>6fdd74d0-3405</ser:SessionId>
</ser:SessionHeader>
</soapenv:Header>
<soapenv:Body>
<ser:SaveProgressForUser>
<!--Optional:-->
<ser:userName>TestUser</ser:userName>
<!--Optional:-->
<ser:answerFile><![CDATA[<AnswerFile Version="2"><HeaderInfo></HeaderInfo><ps><p pid="e32ae8d7-017b-4d36-9c4c-09f6822362b3"><qs><q qid="b4c31241-c6c9-4013-9740-4cbc520dd10a" SelectedValue="" /><repeat c="2" guid="32418f0a-7e13-40db-872d-a42e220bfc15"><qs i="0" guid="b2f16b48-ca3d-4a06-85e8-7373ead7ccfe"><q qid="7834cb57-ba6f-4063-8a02-4925079d7e04" SelectedValue="" /></qs><qs i="1" guid="cb9e34a2-ecd8-4e06-8072-a6cb682fb655"><q qid="7834cb57-ba6f-4063-8a02-4925079d7e04" SelectedValue="" /></qs></repeat></qs></p></ps></AnswerFile>]]>
</ser:answerFile>
</ser:SaveProgressForUser>
</soapenv:Body>
</soapenv:Envelope>
So, in my Java client, I declare AnswerFile as a string and while invoking the Webservice I set this string using the setter.
String answerFile = "<![CDATA[<AnswerFile Version="2"><HeaderInfo></HeaderInfo><ps><p pid="e32ae8d7-017b-4d36-9c4c-09f6822362b3"><qs><q qid="b4c31241-c6c9-4013-9740-4cbc520dd10a" SelectedValue="" /><repeat c="2" guid="32418f0a-7e13-40db-872d-a42e220bfc15"><qs i="0" guid="b2f16b48-ca3d-4a06-85e8-7373ead7ccfe"><q qid="7834cb57-ba6f-4063-8a02-4925079d7e04" SelectedValue="" /></qs><qs i="1" guid="cb9e34a2-ecd8-4e06-8072-a6cb682fb655"><q qid="7834cb57-ba6f-4063-8a02-4925079d7e04" SelectedValue="" /></qs></repeat></qs></p></ps></AnswerFile>]]>"
However, smart that Java is, it encodes the < and > within the string to < and > and my generated request contains the <ser:answerFile> with an encoded value, something like below:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://services.intel.com/">
<soapenv:Header>
<ser:SessionHeader>
<ser:SessionId>6fdd74d0-3405</ser:SessionId>
</ser:SessionHeader>
</soapenv:Header>
<soapenv:Body>
<ser:SaveProgressForUser>
<!--Optional:-->
<ser:userName>TestUser</ser:userName>
<!--Optional:-->
<ser:answerFile><![CDATA[<AnswerFile Version="2"><HeaderInfo><ps><p pid="e32ae8d7-017b-4d36-9c4c-09f6822362b3"><qs><q qid="b4c31241-c6c9-4013-9740-4cbc520dd10a" SelectedValue="" /><repeat c="2" guid="32418f0a-7e13-40db-872d-a42e220bfc15"><qs i="0" guid="b2f16b48-ca3d-4a06-85e8-7373ead7ccfe"><q qid="7834cb57-ba6f-4063-8a02-4925079d7e04" SelectedValue="" /></qs><qs i="1" guid="cb9e34a2-ecd8-4e06-8072-a6cb682fb655"><q qid="7834cb57-ba6f-4063-8a02-4925079d7e04" SelectedValue="" /></qs></repeat></qs></p></ps></AnswerFile>]]>
</ser:answerFile>
</ser:SaveProgressForUser>
</soapenv:Body>
</soapenv:Envelope>
So, how can I avoid this encoding and pass the answerFile value as is (With < and >).
I cannot create a document-element object structure and set, coz the setter only accepts a string as per the WSDL.
Any help will be appreciated. Please yell at me if any info is missing in the problem description.
Like I said, I havent used the Document builder approach, instead just a trivial String object to represent the CDATA XML.
An excerpt of the class can be seen below.
public static void main(String[] args) throws Exception {
try {
String username = "ServiceUser";
String password = "Help#";
String masquaradeUsername = "TestUser";
NtlmAuthenticator authenticator = new NtlmAuthenticator(username, password);
Authenticator.setDefault(authenticator);
Platform platform = new Platform();
PlatformSoap client = platform.getPlatformSoap();
String answerXML = "<![CDATA[<AnswerFile Version=\"2\"><HeaderInfo></HeaderInfo><ps><p pid=\"e32ae8d7-017b-4d36-9c4c-09f6822362b3\"><qs><q qid=\"b4c31241-c6c9-4013-9740-4cbc520dd10a\" SelectedValue=\"\" /><repeat c=\"2\" guid=\"32418f0a-7e13-40db-872d-a42e220bfc15\"><qs i=\"0\" guid=\"b2f16b48-ca3d-4a06-85e8-7373ead7ccfe\"><q qid=\"7834cb57-ba6f-4063-8a02-4925079d7e04\" SelectedValue=\"\" /></qs><qs i=\"1\" guid=\"cb9e34a2-ecd8-4e06-8072-a6cb682fb655\"><q qid=\"7834cb57-ba6f-4063-8a02-4925079d7e04\" SelectedValue=\"\" /></qs></repeat></qs></p></ps></AnswerFile>]]>";
String saveGUID = client.saveProgressForUser(masquaradeUsername, answerXML);
} catch(Exception e) {
LOGGER.info("Exception encountered####");
}
}
Hope this information helps you understand my problem better.
You have two options for solving this problem.
The first is to remove the <![CDATA[ ... ]]> escaping from the XML snippet entirely. It appears that the library class PlatformSoap already escapes the XML symbols in the content.
Since PlatformSoap excapes the string when you put it in to the XML document, if you remove the CDATA from the String, it should escape the document to:
<ser:answerFile><AnswerFile Version="2">< ......... </repeat></qs></p></ps></AnswerFile>
</ser:answerFile>
That is valid XML, and, on the far side of the connection it should parse the XML properly, and restore the original content, without the CDATA.
If the far side of the connection is well-behaved, the above should just work.
On the other hand, the far side may expect to find an actual CDATA section, at which point, you should do 2 things:
file a bug against the people who do not conform to XML standards
modify the PlatformSoap class to provide a method/mechanism that forces the CDATA section around the content, and supply the un-wrapped string to that new method on PlatformSoap
In summary:
CDATA is purely a convenience wrapper that allows you to have unescaped content.
Escaping it instead of using CDATA is semantically the same, there is no difference in the logical meaning/content of the XML.
Whether the far side of the service honours XML convention or not is uncertain
if it does, then just use the escaped version (no CDATA)
if it does not, then change the far side.
if it does not, and you can't change the far side, then change your code in PlatformSoap