Is schema-aware streaming possible? - saxon

Assume I have simple schema that uses xs:sequence (not xs:all).
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns="mynamespace" xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="mynamespace" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:element name="root">
<xs:complexType>
<xs:sequence>
<xs:element name="RepeatingElement" type="repeatingElementType" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="repeatingElementType">
<xs:sequence>
<xs:element name="FirstElement" type="xs:string"/>
<xs:element name="SecondElement" type="xs:string"/>
<xs:element name="ThirdElement" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
I then write a schema-aware transform, that consumes the nodes in sequential order.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="3.0" xmlns:n1="mynamespace" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml"/>
<xsl:mode streamable="yes"/>
<xsl:import-schema namespace="mynamespace" schema-location="sampleSchema.xsd"></xsl:import-schema>
<xsl:template match="/">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="element(*, n1:repeatingElementType)">
<xsl:value-of select="n1:FirstElement" />
<xsl:value-of select="n1:SecondElement" />
<xsl:value-of select="n1:ThirdElement" />
</xsl:template>
</xsl:stylesheet>
Right now, streaming engines (i.e. SAXON) will throw an error.
Template rule is declared streamable but it does not satisfy the streamability rules. * There is more than one consuming operand: {xsl:value-of} on line 10, and {xsl:value-of} on line 11
Given the engine knows the order the elements can appear, shouldn't it be able to determine during analysis phase that the style-sheet is streamable?

The streamability analysis built in to the XSLT 3.0 spec, and implemented in Saxon, does not take account of any knowledge of sibling order that might come from schema knowledge. It could be done in theory, but the rules would get very complex to handle any but the most simple cases. (Consider, for example, an xsl:choose in the stylesheet that corresponds structurally to an xs:choice in the schema...) The WG made an early decision to exclude that from the scope.

Related

SOAP WSDL Formatting (THTTPRIO)

I'm consuming a SOAP Web Service that requires the text ":com" in some of the tags. For example instead of
<soapenv:Envelope >
<soapenv:Body>
<RunSimpleTrip>
<c>
<CompanyCode>CompanyCode</CompanyCode>
<Password>Password</Password>
<Username>Username</Username>
</c>
<BasicTrip>
<Comments />
<Driver>Some Driver</Driver>
<EndOdometer />
...
</BasicTrip>
</RunSimpleTrip>
</soapenv:Body>
</soapenv:Envelope>
It needs to be
<soapenv:Envelope >
<soapenv:Body>
<RunSimpleTrip>
<c>
<com:CompanyCode>CompanyCode</com:CompanyCode>
<com:Password>Password</com:Password>
<com:Username>Username</com:Username>
</c>
<BasicTrip>
<com:Comments />
<com:Driver>Some Driver</com:Driver>
<com:EndOdometer />
...
</BasicTrip>
</RunSimpleTrip>
</soapenv:Body>
</soapenv:Envelope>
Notice how not all the tags need the prefix (like the c or BasicTrip tags). Just the inner ones, the fields of the objects.
Am I stuck with doing a StringReplace on each individual tag, or is there an option I'm missing? Is there some way to toggle the importer or WSDL .pas file to do this by itself?
This is the same question, which received no good answer at the time Delphi HttpRio SOAPHTTPClient does not add a prefix to namespaced variables . And just like the question, when I generate this via soapUI it places the ":com" on the needed tags.
Edit: Here's a snippet of the WSDL that describes a BasicTrip
<xs:complexType name="BaseTrip">
<xs:sequence>
<xs:element name="Comments" nillable="true" type="xs:string"/>
<xs:element name="Driver" nillable="true" type="xs:string"/>
<xs:element name="EndOdometer" type="xs:decimal"/>
<xs:element name="GetMapPoints" type="xs:boolean"/>
...
</xs:sequence>
</xs:complexType>

Create output Xml file from XML and XSD using DataSet

I've got two example files: note.xml and note.xsd. I would like to combine this two files using DataSet and create output XML file, based on this operation. How can i do it?
note.xml
<?xml version="1.0"?>
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>
note.xsd
<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="https://www.w3schools.com"
xmlns="https://www.w3schools.com"
elementFormDefault="qualified">
<xs:element name="note">
<xs:complexType>
<xs:sequence>
<xs:element name="to" type="xs:string"/>
<xs:element name="from" type="xs:string"/>
<xs:element name="heading" type="xs:string"/>
<xs:element name="body" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
UPDATE
Basically, i would like to combine XSD and XML and create output XML file. I want to use something like data table relations(DataSet)
Then after combine, we can decide based on data type(string, int..), which for example: dataform can store this.

Invalid Content Was Found Starting With Element 'country'. One Of '{country}' Is Expected.. Line '10', Column '14'

I am trying to resolve this issue but could not understand the root cause of this error:
Invalid Content Was Found Starting With Element 'country'. One Of '{country}' Is Expected.. Line '10', Column '14'
Here is my xml:
<?xml version="1.0"?>
<!--DTD file reference-->
<!--<!DOCTYPE countries SYSTEM "http://localhost:8080/ajaxprac/file.dtd">-->
<!--DTD file reference-->
<!---->
<countries xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://localhost:8080/ajaxprac"
xsi:schemaLocation="http://localhost:8080/ajaxprac fileSchema.xsd">
<country>
<name>pakistan</name>
<cities>
<city>Kassowal</city>
<city>Faisalabad</city>
<city>Multan</city>
</cities>
</country>
<country>
<name>india</name>
<cities>
<city>Agra</city>
<city>Amritsar</city>
<city>Ayodhya</city>
</cities>
</country>
</countries>
and xsd file for this is:
<?xml version="1.0"?>
<!--
To change this template, choose Tools | Templates
and open the template in the editor.
-->
<xs:schema version="1.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://localhost:8080/ajaxprac"
xmlns="http://localhost:8080/ajaxprac">
<xs:element name="countries" type="countriesType"/>
<xs:element name="name" type="xs:string"/>
<xs:element name="city" type="xs:string"/>
<xs:complexType name="countriesType">
<xs:sequence>
<xs:element name="country" type="countryType"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="countryType">
<xs:sequence>
<xs:element ref="name"/>
<xs:element name="cities" type="citiesType"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="citiesType">
<xs:sequence>
<xs:element ref="city"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
As written, your schema expects the "global" countries, name and city elements to be in the http://localhost:8080/ajaxprac namespace, but the "local" elements (those declared inside a complexType, i.e. country and cities) to be in no namespace. You probably want to add elementFormDefault="qualified", i.e.
<xs:schema version="1.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://localhost:8080/ajaxprac"
xmlns="http://localhost:8080/ajaxprac"
elementFormDefault="qualified">
which applies the targetNamespace to local, as well as global, element declarations.

Groovy/Grails Using WSClient to consume .net web service

I'm pretty new to both Grails/Groovy/Web services and i'm consuming a .net web service ..
I have some code connects to the service using grails WS-client plugin :
WebService webService
def result = {
def wsdl =
ApplicationHolder.application.parentContext.getResource('WEB-INF/productsSoap.wsdl')
def proxy = webService.getClient(wsdl.getURL().toString())
def productTypeListResponse = proxy.ProductTypeList()
}
I also used soapUI to examine the data returned from the web service which gave ..
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<ProductTypeListResponse xmlns="http://tempuri.org/">
<ProductTypeListResult>
<xs:schema id="ProductTypeListResult" xmlns=""
xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xs:element name="ProductTypeListResult" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="ProductTypeListResult">
<xs:complexType>
<xs:sequence>
<xs:element name="PRD_TypeId" type="xs:int" minOccurs="0"/>
<xs:element name="PRD_TypeName" type="xs:string" minOccurs="0"/>
<xs:element name="PRD_Type" type="xs:string" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>
<diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1">
<ProductTypeListResult xmlns="">
<ProductTypeListResult diffgr:id="ProductTypeListResult1" msdata:rowOrder="0">
<PRD_TypeId>2</PRD_TypeId>
<PRD_TypeName>ProdType2</PRD_TypeName>
<PRD_Type>S</PRD_Type>
</ProductTypeListResult>
<ProductTypeListResult diffgr:id="ProductTypeListResult2" msdata:rowOrder="1">
<PRD_TypeId>3</PRD_TypeId>
<PRD_TypeName>ProdType3</PRD_TypeName>
<PRD_Type>C</PRD_Type>
</ProductTypeListResult>
<ProductTypeListResult diffgr:id="ProductTypeListResult3" msdata:rowOrder="2">
<PRD_TypeId>4</PRD_TypeId>
<PRD_TypeName>ProdType4</PRD_TypeName>
</ProductTypeListResult>
</ProductTypeListResult>
</diffgr:diffgram>
</ProductTypeListResult>
</ProductTypeListResponse>
>
which is a .net dataset ..
So my question is how do i get at the information using my productTypeListResponse ? Can anyone give me a pointer ?
The WS Client should generate the proper code to access the result. I do not fully understand the wsdl that the .net service generates, but you should have methods such as
productTypeListResponse.ProductTypeListResult
on your response object. Check the example on groovy WS client site.
IMHO I would suggest you to use a more mature library such as spring ws

biztalk map from unbounded with subelement to unbounded

source XSD structure:
documents (min occurs 1, max occurs 1)
document (min occurs 1, max occurs unbounded)
filename (min occurs 1, max occurs 1)
destination XSD structure:
documents (min occurs 1, max occurs 1)
filename (min occurs 1, max occurs unbounded)
How can this be done in the BizTalk mapper ?
(edit):
The 1st provided solution was my first implementation, but it seems that the Test Map option(right-mouse on the BizTalk map .btm file) in BizTalk sometimes needs an extra compile (I only saved the map and then I tested the map with the Test Map option). Now it works.
In Biztalk 2009 (and presumably also 2006) just connect the "filename" nodes.
Source schema:
<?xml version="1.0" encoding="utf-16"?>
<xs:schema xmlns:b="http://schemas.microsoft.com/BizTalk/2003" xmlns="http://source" targetNamespace="http://source" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="documents">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="1" maxOccurs="unbounded" name="document">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="1" maxOccurs="1" name="filename" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Destination schema:
<?xml version="1.0" encoding="utf-16"?>
<xs:schema xmlns:b="http://schemas.microsoft.com/BizTalk/2003" xmlns="http://destination" targetNamespace="http://destination" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="documents">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="1" maxOccurs="unbounded" name="filename" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Map:
<?xml version="1.0" encoding="utf-16"?>
<mapsource Name="BizTalk Map" BizTalkServerMapperTool_Version="2.0" Version="2" XRange="100" YRange="420" OmitXmlDeclaration="Yes" TreatElementsAsRecords="No" OptimizeValueMapping="Yes" GenerateDefaultFixedNodes="Yes" PreserveSequenceOrder="No" CopyPIs="No" method="xml" xmlVersion="1.0" IgnoreNamespacesForLinks="Yes">
<SrcTree>
<Reference Location="source.xsd" />
</SrcTree>
<TrgTree>
<Reference Location="destination.xsd" />
</TrgTree>
<ScriptTypePrecedence>
<CSharp Enabled="Yes" />
<ExternalAssembly Enabled="Yes" />
<VbNet Enabled="Yes" />
<JScript Enabled="Yes" />
<XsltCallTemplate Enabled="Yes" />
<Xslt Enabled="Yes" />
</ScriptTypePrecedence>
<TreeValues>
<TestValues />
<ConstantValues />
</TreeValues>
<Pages>
<Page Name="Page 1">
<Links>
<Link LinkID="1" LinkFrom="/*[local-name()='<Schema>']/*[local-name()='documents']/*[local-name()='document']/*[local-name()='filename']" LinkTo="/*[local-name()='<Schema>']/*[local-name()='documents']/*[local-name()='filename']" Label="" />
</Links>
<Functoids />
</Page>
</Pages>

Resources