I have jax-ws service implemented using cxf with jaxb binding. It receives xml from another downstream service, Unmarshals this xml in to a POJO and saves it to persistent caching store. Future requests are served from this persistent store. Some times the xml received from downstream service contains xmlns="". The service is able to unmarshal the xml from the persistent caching store but when it marshals back the response to the client, the xml is not well formed.
Here is the xml i.e. received from downstream service. Notice the PolicyID element with xmlns="".
<message:RetrieveOrderResponse
xmlns:common="urn:xyz:om:common:defn:v1" xmlns:message="urn:xyz:om:order:messages:v1"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<common:MessageInfo CreateDateTime="2015-04-17T13:13:36.819-07:00"
MessageGUID="d8ad2956-ff69-45ff-9d57-c30dc50569a1" TransactionGUID="a772169a-b138-40e7-8d16-ca86b68d38b8">
<common:DebugTraceBoolean>true</common:DebugTraceBoolean>
</common:MessageInfo>
<common:MessageStatus>
<common:Status>Success</common:Status>
</common:MessageStatus>
<common:OrderList>
<common:Order>
<common:OrderLineList>
<common:OrderLine>
<common:OrderLineData namespace="urn:xyz:e3:data:abc:types:v1"
type="xyzProduct">
<ns2:xyzProduct xmlns:datatype="urn:xyz:om:supply:datatype:defn:v1"
xmlns:finance="urn:xyz:e3:data:financetypes:defn:v4"
xmlns:internal="urn:xyz:cc:es:order:internal" xmlns:min="xalan://org.jaxen.function.MinDateTimeFunction"
xmlns:ns2="urn:xyz:e3:data:abc:types:v1" xmlns:ns3="urn:xyz:e3:data:basetypes:defn:v4"
xmlns:ns4="urn:xyz:e3:data:financetypes:defn:v4" xmlns:ns5="urn:xyz:e3:data:timetypes:defn:v4"
xmlns:ns6="urn:xyz:e3:data:messagetypes:defn:v5" xmlns:ns7="urn:xyz:e3:data:placetypes:defn:v4"
xmlns:ns8="urn:xyz:om:supply:messages:defn:v1">
<PolicyID xmlns="" />
<ns2:abcProduct>
<ns2:DiningSeatingInformation>
<BookingStatusCode xsi:nil="true" />
<DinSeatingCode xsi:nil="true" />
</ns2:DiningSeatingInformation>
</ns2:abcProduct>
</ns2:xyzProduct>
</common:OrderLineData>
</common:OrderLine>
</common:OrderLineList>
</common:Order>
</common:OrderList>
This xml is subjected to the following steps.
unmarshal in to a POJO
marshal the POJO back to xml
unmarshal the xml from step 2 back to POJO
marshal the POJO from step 3 to xml
The resulting xml from step 4 is not well formed. In the example below, the start tag for OrderLineData is bound to valid namespace prefix but the end tag is unbound. If I remove the xmlns="" from the xml then step4 outputs well formed xml. Here is the badly-formed xml.
true
Success
Any hints on how to handle such xml?
Are you using classes generated by some XSD ? if yes make sure you have package-info.java class in the generated package. This class is responsible for namespace handling and it is used during marshal/ unmarshal process.
Related
I'm trying to send a quite simple JSON message from BizTalk.
{
"Value": 1
}
I set the type of the "Value" field to xs:int in my xml schema
<xs:element minOccurs="1" maxOccurs="1" name="Value" type="xs:int" />
But it keeps generating the wrong JSON message.
{
"Value": "1"
}
Not sure what I'm doing wrong here. Does anybody have some tips?
There can be multiple issues at work here.
Your XML payload is not going through a XML Dissasembler or Assembler before reaching the JSON Encoder, and hence the Message Type isn't set correctly, in which case it is not using the schema to determine the correct date types.
You have another earlier element in your schema with the same name but a different type. It will use the type from the first one for all elements with the same name. This was a bug in BizTalk 2013 R2, and I think it was still there in BizTalk 2016 and could cause some strange errors, especially if you had a Records (complex types) and Element (simple types) with the same name. e.g FIX: JSON encoder unable to handle XML schema with the same name for record and one of its elements in CU 7
Biztalk Embedded JSON Encoder has the ability to recognize schema of XML processed and should recognize xs:int value from schema and encoded without quotes.
But sometimes (as Sandro Pereira indicates even often) this encoder throws the error:
Reason: Value cannot be null.
Parameter name: key
That was my case. I had to use a custom JSON Encoder that recognizes XML datatype somehow.
My solution was:
Use this build of Newtonsoft.Json library that uses json:Type argument as indicator of XML tag datatype.
Create a custom JSON Encoder that uses the previous library
Create custom Complex Type in separate schema with targetNamespace = "http://james.newtonking.com/projects/json"
Note that attribute Type need to be Qualified
Import above schema in Your target schema using prefix json
Use this type as Data Structure Type and rename Your parameter.
Map this checking logical existance, to avoid putting argument without value or custom xslt tranform
Usefull sites:
Adding name to attribute
I am new to BizTalk and I need to read some values from a SQL Server table. An example of the result set I am getting is the follow:
<SelectResponse
xmlns="http://schemas.microsoft.com/Sql/2008/05/TableOp/dbo/tableName">
<SelectResult>
<tableName xmlns="http://schemas.microsoft.com/Sql/2008/05/Types/Tables/dbo">
<Message> <item_1> item_1Value </item_1>
<item_2> item_2Value </item_2>
<item_3> item_3Value </item_3>
<item_n> item_3Value </item_n> </Message>
</tableName>
</SelectResult>
</SelectResponse>
So I get my message in BizTalk (the schema is auto-generated from SQL Adapter). What I want is the following:
<SelectResponse
xmlns="http://schemas.microsoft.com/Sql/2008/05/TableOp/dbo/tableName">
<SelectResult>
<tableName xmlns="http://schemas.microsoft.com/Sql/2008/05/Types/Tables/dbo">
<Message>
<item_1> item_1Value </item_1>
<item_2> item_2Value </item_2>
<item_3> item_3Value </item_3>
<item_n> item_3Value </item_n>
</Message>
</tableName>
</SelectResult>
</SelectResponse>
I have the new schema (for item_1, item_2, ...). Considering that <Message> can appear multiple times inside the BizTalk message, what is the easier way to get what I need and how can I do that? Thanks.
The most likely reason you are seeing this is the item Xml content is stored within another Xml structure, Message. Xml stored within Xml is escaped so this isn't an actual problem, it's the expected behavior.
You have several options including:
Use a Stored Procedure that loads and handles the item Xml as Xml and not a string in the result.
In an Orchestration, extract the item Xml, reformat to include a root element and create a new Message based on that.
The problem is how this data has been stored, not how SQL Server is returning it or how BizTalk is presenting it.
I'm trying to use the "Convert XML to JSON" example from WikiBooks here https://en.wikibooks.org/wiki/XQuery/Convert_XML_to_JSON
xquery version "3.0";
declare namespace output="http://www.w3.org/2010/xslt-xquery-serialization";
declare option output:method "json";
declare option output:media-type "application/json";
let $test := <root>
<!-- simple elements -->
<aaa>AAA</aaa>
<bbb>BBB</bbb>
<ccc>CCC</ccc>
<!-- complex (nested) element -->
<ddd>
<eee>
<fff>
<ggg>GGG</ggg>
</fff>
</eee>
</ddd>
<!-- duplicate elements -->
<hhh>HHH1</hhh>
<hhh>HHH2</hhh>
<hhh>HHH3</hhh>
<hhh>HHH4</hhh>
<!-- attributes -->
<iii a1="123" a2="456" a3="789"/>
<!-- attributes with text content-->
<jjj a1="123" a2="456" a3="789">JJJ</jjj>
</root>
return $test
I'm using the Saxon parser, with this command line
java -cp Saxon-HE-9.8.0-8.jar net.sf.saxon.Query xml2json.xqy
But it's still returning the $test variable as xml, what am I missing?
The wikibook article you reference is incorrect. According to the relevant specification, XSLT and XQuery Serialization 3.1, the JSON serialization method treats XML nodes as follows:
A node in the data model instance is serialized to a JSON string by outputting the result of serializing the node using the method specified by the json-node-output-method parameter. The node is serialized with the serialization parameter omit-xml-declaration set to yes and with no other serialization parameters set.
In other words, an XQuery processor like Saxon is supposed to serialize XML nodes as JSON strings.
To achieve the goal promised by the wikibook article, you would need to transform the document into maps and arrays or into an intermediary format that you can feed to the xml-to-json()` function.
I am trying to build a UI based in Angular to retrieve all existing execution lists of Tosca. However, I could not find a REST API that can give the list of folders within a workspace in Tosca. Has anyone tried this route?
You can use the Search task on the projectto find all ExecutionLists.
Example:
{rest_url}/ToscaCommander/{workspace_name}/object/project/task/Search
as a post request with the xml payload:
<Parameters xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Parameter>
<Name>tqlString</Name>
<Type i:nil="true"/>
<Value>->SUBPARTS:TCFolder[Name=?"Execution"]=>SUBPARTS:ExecutionList</Value>
</Parameter>
</Parameters>
This will give you a list of object ids of the ExecustionLists contained in the Execution folder of the project. You can fetch the objects one by one with this request afterwards:
{rest_url}/ToscaCommander/{workspace_name}/object/{object_id}
Credits for this solution go to the development team of ToscaCommander - they provided it.
P.S.: as an answer for your comment:
Yes, there is a json equivalent of the body - but you do not need it. Anyway, here is the equivalent:
[{
"Name":"tqlString",
"Value":"->SUBPARTS:TCFolder[Name=?\"Execution\"]=>SUBPARTS:ExecutionList"
}]
If you want to get a json response (regardless of the request's payload's format) make sure your web.config sets AutomaticFormatSelectionEnabled to true (which should be the case). Then, in your requests, set the accept header accordingly:
Accept: application/json
I use a WebService to transform and XmlDocument into a PDF.
The XmlDocument I send to the Web service looks like this.
<?xml version="1.0" encoding="utf-16" ?>
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
...
</fo:root>
I had a problem so I went in debug mod to find out that when the XmlDocument object is transferred from my asp website itself to the Web Service which works on .NET 1.1 sees his
xml tag. Is there a reason why this tag is removed? Could it be caused by the SOAP response?
Is there a way around other than manually add the tag back in the document?
Edit
To answer John's question, yes I mean the processing instruction. It just goes off and I was wondering why because the library I use to convert doesn't work without it. If I manually add it, it works fine but I just wanted to know why it disappear.
Edit 2
Even if it isn't a tag, the library that requires the XmlDocument just doesn't work without it that's why I need it. Other than that, the rest of the document is processed correctly. The generated Reference.cs from the Web Reference looked like this for the called method :
/// <remarks/>
[System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://tempuri.org/GeneratePdfFromXml", RequestNamespace="http://tempuri.org", ResponseNamespace="http://tempuri.org", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
[return: System.Xml.Serialization.XmlElementAttribute(DataType="base64Binary")]
public byte[] GeneratePdfFromXml(XmlNode FormattedObjectXml) {
object[] results = this.Invoke("GeneratePdfFromXml", new object[] {
FormattedObjectXml});
return ((byte[])(results[0]));
}
It is the same issue as another problem I had, in which the XmlDocument are referenced as XmlNode since the SOAP response is a XmlDocument itself.
I just changed this to a string ; MyXmlDocument.OuterXml;
That way, everything is kept and no problem.
It is most likely an encoding issue. The XML Declaration is claiming the document is in UTF-16, which is two bytes per character. The other library probably is assuming, in its absence, some other encoding.
You will never get an XML Declaration or processing instruction passed to via an XmlNode, XmlElement or XmlDocument parameter to an ASMX service. The reason is obvious if you think about it. The SOAP Request would be something like:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" >
<SOAP-ENV:Body>
<parameter>
<?xml version="1.0" encoding="utf-16" ?>
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
</fo:root>
</parameter>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
But an XML declaration can only appear at the very beginning of the document, so this is invalid.
The solution, as you found, is to send this XML as a string. Make your parameter type string, and either use XmlNode.OuterXml.