Liquid Mapping for conversion from xml to json - xml-to-json

I have this xml part of Data:
<xs:element name="DESCR">
<xs:complexType>
<xs:sequence>
<xs:element name="ADDITIONAL">
<xs:complexType>
<xs:sequence>
<xs:element name="DESCR_CODE">
<xs:complexType>
<xs:attribute name="CODE" type="xs:unsignedInt" use="required" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>]
I am interested in mapping this xml to json as:
"DESCR": {
"ADDITIONAL": {
"DESCR_CODE": "{{DESCR.ADDITIONAL.DESCR_CODE.CODE}}"
}
}
but I don't get the value of attribute CODE.
How could the value of an XML attribute be mapped to JSON?

Related

Element type in xsd is referring its own Complex type

I have xsd like this -
<xs:complexType name="ChoiceListItem">
<xs:sequence>
<xs:element name="childChoices" maxOccurs="unbounded" minOccurs="0" nillable="true" type="tns:ChoiceListItem"/>
<xs:element name="name" nillable="true" type="xsd:string"/>
<xs:element name="stringValue" nillable="true" type="xsd:string"/>
<xs:element name="integerValue" nillable="true" type="xsd:int"/>
</xs:sequence>
</xs:complexType>
Here you can see that my childChoices type is ChoiceListItem under which it is defined. Here is my Java class -
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "ChoiceListItem", propOrder = {
"childChoices",
"name",
"stringValue",
"integerValue"
})
public class ChoiceListItem {
#XmlElement(nillable = true)
protected List<ChoiceListItem> childChoices;
#XmlElement(required = true, nillable = true)
protected String name;
#XmlElement(required = true, nillable = true)
protected String stringValue;
#XmlElement(required = true, type = Integer.class, nillable = true)
protected Integer integerValue;
When I run it in SOAPUI it did not display the childChoices value but displays the other three items. Here is my output response -
<ns3:getChoiceListItemsResponse xmlns:ns3="http://getservice.service">
<getChoiceListItemsReturn>
<items>
<ChoiceListItem>
<name>AD SERVICE</name>
<stringValue>AD SERVICE</stringValue>
<integerValue xsi:nil="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>
</ChoiceListItem>
I guess xsd is not defined properly..Can somebody please help me in defining correct xsd in which sequence element type refer to same Complex type?
I have solved it by making changes into my xsd
<xs:complexType name="ChoiceListItem">
<xs:sequence>
<xs:element name="childChoices" nillable="true" type="tns:ChoiceListItemArray"/>
<xs:element name="name" nillable="true" type="xsd:string"/>
<xs:element name="stringValue" nillable="true" type="xsd:string"/>
<xs:element name="integerValue" nillable="true" type="xsd:int"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="ChoiceListItemArray">
<xs:sequence>
<xs:element maxOccurs="unbounded" minOccurs="0" name="ChoiceListItem" nillable="true" type="tns:ChoiceListItem"/>
</xs:sequence>
</xs:complexType>

how to extract all values of a XML datasource field to array

I have a XML data source like below:
<xs:element name="block" type="xs:string" minOccurs="0" />
<xs:element name="lot" type="xs:string" minOccurs="0" />
<xs:element name="wafer" type="xs:string" minOccurs="0" />
Now I want to create a formula which need all block+lot as a string with each record as a single line.
so suppose the data is
<xs:element name="block" type="xs:string" minOccurs="0" >A1</block>
<xs:element name="lot" type="xs:string" minOccurs="0" >B1</lot>
<xs:element name="wafer" type="xs:string" minOccurs="0" >C1</wafer>
<xs:element name="block" type="xs:string" minOccurs="0" >A2</block>
<xs:element name="lot" type="xs:string" minOccurs="0" >B2</lot>
<xs:element name="wafer" type="xs:string" minOccurs="0" >C2</wafer>
then the result string is A1B1/nA2B2
How to do it?I tried to use variable and while do loop, but how to let the variable point to next record? Thx.

scalaxb fails when an element and an attribute at the same level having the same name

I am trying to use the sbt-scalaxb to generate bindings for the FixRepository.xsd and it does not like the SUBJ.
As a last resort, of cause, I can to slightly change the schema, but is there maybe a way to tune the sbt-scalaxb to understand the original file?
The XSD fragment the sbt-scalaxb does not like is:
xml
<xs:element name="component">
<xs:complexType>
<xs:sequence>
<xs:element ref="messageEntity" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attributeGroup ref="entityAttribGrp"/>
<xs:attribute name="id" type="id_t" use="required"/>
<xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="type" type="ComponentType_t" use="required"/>
<xs:attribute name="repeating" type="BOOL_t" use="optional"/>
<xs:attribute name="category" type="xs:string" use="optional"/>
<xs:attribute name="abbrName" type="xs:string" use="optional"/>
<xs:attribute name="notReqXML" type="BOOL_t" use="optional"/>
<!-- would like to force a description of the component -->
</xs:complexType>
</xs:element>
Figured out myself: scalaxbAttributePrefix setting adds a prefix to the attribute properties.
build.sbt
scalaxbAttributePrefix in (Compile, scalaxb) := Some("attr")
Generated FixRepository.scala
case class Fix(
...,
components: ...fixrepo.Components,
...,
attributes: Map[String, scalaxb.DataRecord[Any]] = Map()
) {
...
lazy val attrComponents = attributes("#components").as[BOOL_t]
...
}

How to tell JAXB not to generate #XmlSchemaType Annotation

following xsd (partial):
<xs:complexType name="Fruit">
<xs:sequence>
<xs:element name="type" type="FruitType"/>
</xs:sequence>
</xs:complexType>
<xs:simpleType name="FruitType">
<xs:restriction base="xs:string">
<xs:enumeration value="ABC">
</xs:enumeration>
<xs:enumeration value="DEF">
</xs:enumeration>
<xs:enumeration value="GHI">
</xs:enumeration>
<xs:enumeration value="JKL">
</xs:enumeration>
</xs:restriction>
</xs:simpleType>
Generating code with xjc will generate the following java code (FruitType is an Enum):
#XmlElement(required = true)
#XmlSchemaType(name = "string")
protected FruitType fruit;
When generating a SOAP WebService with JAX-WS the following element will be generated:
<xs:element name="type" type="xs:string"/>
Which ist obviously wrong. I'd expect this to be
<xs:element name="type" type="FruitType"/>
If I delete this line by hand
#XmlSchemaType(name = "string")
in my Java Code everything in the wsdl is fine :
<xs:element name="type" type="tns:FruitType"/>
So the question is: How can I tell JAXB not to generate the #XmlSchemaType?
Instead of referencing FruitType with type
<xs:complexType name="Fruit">
<xs:sequence>
<xs:element name="type" type="FruitType"/>
</xs:sequence>
</xs:complexType>
the trick ist to have a simpleType inline:
<xs:complexType name="Fruit">
<xs:sequence>
<xs:element name="type">
<xs:simpleType>
<xs:restriction base="FruitType"/>
</xs:simpleType>
</xs:element>
</xs:sequence>
</xs:complexType>
this will generate the correct java file and WSDL:
<xs:element name="type" type="tns:FruitType"/>

Accessing SOAP API with Perl. Long Int -problems?

I have at my hands a SOAP API that has plenty of functionality, but from which I only need two methods: adding user to a database and deleting user from a database.
Currently I am locked to Perl as the language for this task.
Because deleting a user takes in as the only parameter the "id" of the user (not "userId" as in username), I need to define it myself rather than relying on MySQL's auto_increment.
Relevant parts from the WSDL:
<xs:element name="saveLocalUserEx">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="user" nillable="true" type="ns2:LocalUser"/>
<xs:element minOccurs="0" name="requestingUser" nillable="true" type="xs:string"/></xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="LocalUser">
<xs:sequence>
<xs:element minOccurs="0" name="dbData" nillable="true" type="xs:string"/>
<xs:element minOccurs="0" name="description" nillable="true" type="xs:string"/>
<xs:element minOccurs="0" name="displayName" nillable="true" type="xs:string"/>
<xs:element minOccurs="0" name="domainName" nillable="true" type="xs:string"/>
<xs:element minOccurs="0" name="enabled" type="xs:boolean"/>
<xs:element minOccurs="0" name="firstName" nillable="true" type="xs:string"/>
<xs:element minOccurs="0" name="id" nillable="true" type="xs:long"/>
<xs:element minOccurs="0" name="lastName" nillable="true" type="xs:string"/>
<xs:element minOccurs="0" name="loginId" nillable="true" type="xs:string"/>
<xs:element minOccurs="0" name="loginPasswordHash" nillable="true" type="xs:string"/><xs:element minOccurs="0" name="loginPasswordHashType" type="xs:int"/>
<xs:element minOccurs="0" name="preOrSelfProvisioned" type="xs:boolean"/>
<xs:element minOccurs="0" name="DEFAULT_PASSWORD_HASH_TYPE" type="xs:int"/>
<xs:element minOccurs="0" name="PKCS5_REVERSIBLE_HASH_TYPE" type="xs:int"/>
<xs:element minOccurs="0" name="SHA1_NON_REVERSIBLE_HASH_TYPE" type="xs:int"/>
<xs:element minOccurs="0" name="STR_DEFAULT_ADMIN_NAME" nillable="true" type="xs:string"/><xs:element minOccurs="0" name="STR_DEFAULT_DOMAIN" nillable="true" type="xs:string"/><xs:element minOccurs="0" name="STR_DEFAULT_SPONSOR_NAME" nillable="true" type="xs:string"/>
</xs:sequence>
</xs:complexType>
Here are (relevant parts) of the code I first wrote.
my $soap = SOAP::Lite
->uri($uri)
->proxy($proxy);
sub SOAP::Transport::HTTP::Client::get_basic_credentials {
return 'abc' => 'abc';
}
my $test_id = 1515;
# Preparing data for API query for saving the new user.
my $data = SOAP::Data->name("LocalUser" =>
\SOAP::Data->value(
SOAP::Data->name("loginId" => $new_username),
SOAP::Data->name("enabled" => true),
SOAP::Data->name("domainName" => $domainname),
SOAP::Data->name("loginPasswordHash" => $hash),
SOAP::Data->name("id" => $test_id),
SOAP::Data->name("description" => 'Guest User Account generated on: ' . localtime()),
SOAP::Data->name("displayName" => 'Guest')
)
);
my $som = $soap->saveLocalUserEx($data);
print Dumper $som->result();
It almost does the job. In the matter of fact; API accepts this query, result is success and a new user is generated. The problem is, that id field in the database is still MySQL auto_incremented, and not 1515 I tried to give it this time. Then I started thinking that maybe I need to type the parameter explicitly to long, because wsdl states the type for id is xs:long.
I've tried modifying my code with:
SOAP::Data->type('xs:long')->name("id" => $test),
and
SOAP::Data->type('long')->name("id" => $test),
But these didn't help. API query succeeds, but id is not made to 1515.
Do you guys have any idea how to make this work? Thanks!