xs:choice embedded in xs:sequence prevents the use of a union - web-services

I have the following xsd
<xsd:complexType name="myID">
<xsd:choice>
<xsd:element name="testID" type="priv:testID"/>
<xsd:sequence>
<xsd:element name="newID" type="priv:newID"/>
<xsd:element name="testID" type="priv:testID" minOccurs="0"/>
</xsd:sequence>
</xsd:choice>
</xsd:complexType>
Everything is under priv namespace. The problem is that it looks like that myID is a union. It might be a testID or a sequence with newID and testID. When I compile it with wsdl2h from gsoap I am taking the message:
Note: <xs:choice> with embedded
<xs:sequence> or <xs:group>
prevents the use of a union
Is the above XSD correct?

In general the XML type myID can be declared as you described. The conflict exist probably in connection with your definition of the types priv:testID and priv:testID which definition you not included. For example the schema
<?xml version="1.0" encoding="utf-8"?>
<xsd:schema targetNamespace="http://www.ok-soft-gmbh.com/xml/xsd/1.0/XMLSchema.xsd"
elementFormDefault="qualified"
xmlns:priv="http://www.ok-soft-gmbh.com/xml/xsd/1.0/XMLSchema.xsd"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
>
<xsd:simpleType name="testID">
<xsd:restriction base="xsd:string"/>
</xsd:simpleType>
<xsd:simpleType name="newID">
<xsd:restriction base="xsd:string"/>
</xsd:simpleType>
<xsd:complexType name="myID">
<xsd:choice>
<xsd:element name="testID" type="priv:testID"/>
<xsd:sequence>
<xsd:element name="newID" type="priv:newID"/>
<xsd:element name="testID" type="priv:testID" minOccurs="0"/>
</xsd:sequence>
</xsd:choice>
</xsd:complexType>
<xsd:element name="root" type="priv:myID"/>
</xsd:schema>
will be correct. So if an error exist, it is not in the part which you posted.

Related

Convert schema-aware stylesheet

I have a schema-aware XSLT transformation that works well. However, the anticipated users of the XSLT will likely not have access to a schema-aware processor. Thus, I'd like to write some code that will convert my schema-aware XSLT into an XSLT that can be used by basic level conforming processors.
For my purposes, the use of schema-aware constructs is limited to matching templates, i.e.
<xsl:template match="element(*, Candidate)">...</>
I'm not expecting this to be a fully automatic process. What I would like is to generate an XSLT that would, for every complexType in an XSD, find its use in a specified surfaced XSD element.
Example code:
<xsd:schema xmlns="example.xsd" xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="example.xsd" elementFormDefault="qualified" version="0.0">
<xsd:element name="Candidate" type="Candidate"/>
<xsd:complexType name="Candidate">
<xsd:sequence>
<xsd:element name="Code" type="Code" minOccurs="0" maxOccurs="unbounded"/>
<xsd:element name="Name" type="xsd:string" minOccurs="0"/>
<xsd:element name="PartyId" type="Code" minOccurs="0"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Code">
<xsd:sequence>
<xsd:element name="Value" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
The expected output for the element Candidate would be something like this:
<complexType_usages>
<usage complexType="Code" path="Candidate/Code" />
<usage complexType="Code" path="Candidate/Party" />
</complexType_usages>
It might be simplest to work from a validated instance rather than trying to analyse the schema (so long as the instance is sufficiently representative). For every element, output the type annotation (using saxon:type-annotation) and the path, then take the list of type/path pairs, and eliminate duplicates and redundancy.

How to remove unused namespaces from xsd using xslt. Keeping schema reference namespaces entact

I have an xsd file such as :-
<?xml version="1.0" encoding="UTF-8"?>
<xsd:element xmlns:ns2="http://www.tibco.com/ns/no_namespace_schema_location/UnitTest/TestProcess-End.xsd"
xmlns:ns="http://www.tibco.com/ns/no_namespace_schema_location/UnitTest/TestProcess-Map Data.xsd"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:pd="http://xmlns.tibco.com/bw/process/2003"
xmlns:ns="http://www.tibco.com/namespaces/tnt/plugins/jms"
name="group">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="root">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="a" type="xsd:string" minOccurs="0"/>
<xsd:element name="b" type="xsd:string" minOccurs="0"/>
<xsd:element name="c" type="xsd:string" minOccurs="0"/>
<xsd:element name="d" type="xsd:string" minOccurs="0"/>
<xsd:element name="e" type="xsd:string" minOccurs="0"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element ref="ns:root"/>
<xsd:element ref="ns2:root"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
This contains some un used namespaces, can any one explain how to achieve it with xslt:-
the output desired is :- Please note the namespaces which are used for schema references should be entact.
<?xml version="1.0" encoding="UTF-8"?>
<xsd:element xmlns:ns2="http://www.tibco.com/ns/no_namespace_schema_location/UnitTest/TestProcess-End.xsd"
xmlns:ns="http://www.tibco.com/ns/no_namespace_schema_location/UnitTest/TestProcess-Map Data.xsd"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="group">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="root">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="a" type="xsd:string" minOccurs="0"/>
<xsd:element name="b" type="xsd:string" minOccurs="0"/>
<xsd:element name="c" type="xsd:string" minOccurs="0"/>
<xsd:element name="d" type="xsd:string" minOccurs="0"/>
<xsd:element name="e" type="xsd:string" minOccurs="0"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element ref="ns:root"/>
<xsd:element ref="ns2:root"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
Use exclude-result-prefixes in xslt declaration
In XSLT 2.0, you can do <xsl:copy-of select="/" copy-namespaces="no"/> which will copy the entire document, excluding any namespaces that aren't used in element or attribute names. However, it might remove namespaces that are used only in attribute content, for example ref="ns2:root". Detecting those cases reliably is quite tricky, especially if they are used inside XPath expressions (e.g. in xs:key and xs:keyref constraints).
If you want to remove all "unused" namespaces except those in a $retain list, you could do something like (again XSLT 2.0):
<xsl:template match="*">
<xsl:copy copy-namespaces="no">
<xsl:copy-of select="#*"/>
<xsl:copy-of select="namespace::*[not(name()=$retain)]"/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
and you could perhaps initialize $retain to contain all strings in the stylesheet that match [A-Za-z0-9]:, minus the colon.

XSLT script to match pattern a particular element instance within a specific parent Complextype

I have a schema which is something like this:
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="unqualified" attributeFormDefault="unqualified" version="1.28.0">
<xsd:complexType name="AccountsReceivableInfo_Type">
<xsd:sequence>
<xsd:element ref="SourceIncomePct" minOccurs="0" maxOccurs="1"/>
<xsd:element ref="DuplicateRecordsPct" minOccurs="0" maxOccurs="1"/>
</xsd:sequence>
<xsd:attribute name="id" type="ID"/>
<xsd:attribute name="Locationref" type="IDref"/>
</xsd:complexType>
<xsd:complexType name="AccountsDeleteInfo_Type">
<xsd:sequence>
<xsd:element ref="SourceIncomePct" minOccurs="0" maxOccurs="1"/>
<xsd:element ref="DuplicateRecordsPct" minOccurs="0" maxOccurs="1"/>
</xsd:sequence>
<xsd:attribute name="id" type="ID"/>
<xsd:attribute name="Locationref" type="IDref"/>
</xsd:complexType>
and I am trying to modify it and write an XSLT script to:
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="unqualified" attributeFormDefault="unqualified" version="1.28.0">
<xsd:complexType name="AccountsReceivableInfo_Type">
<xsd:sequence>
<!--<xsd:element ref="SourceIncomePct" minOccurs="0" maxOccurs="1"/>-->
<xsd:element ref="DuplicateRecordsPct" minOccurs="0" maxOccurs="1"/>
</xsd:sequence>
<xsd:attribute name="id" type="ID"/>
<xsd:attribute name="Locationref" type="IDref"/>
</xsd:complexType>
<xsd:complexType name="AccountsDeleteInfo_Type">
<xsd:sequence>
<xsd:element ref="SourceIncomePct" minOccurs="0" maxOccurs="1"/>
<xsd:element ref="DuplicateRecordsPct" minOccurs="0" maxOccurs="1"/>
</xsd:sequence>
<xsd:attribute name="id" type="ID"/>
<xsd:attribute name="Locationref" type="IDref"/>
</xsd:complexType>
XSLT script which i wrote so far is
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsl:output method="xml" encoding="UTF-8" indent="yes"/>
<xsl:template match="xsd:complexType[#name='AccountsReceivableInfo_Type']
/xsd:element[#ref ='SourceIncomePct']">
<xsl:text disable-output-escaping="yes"><!--</xsl:text>
<xsl:sequence select="."/>
<xsl:text disable-output-escaping="yes">--></xsl:text>
</xsl:template>
<xsl:template match="#*|node()">
<xsl:copy><xsl:apply-templates select="#*|node()"/></xsl:copy>
</xsl:template>
</xsl:transform>
What I am trying to do is to modify a big schema like above and automate it and need to read a particular element within a particular complextype parent and modify only that instance like commenting it out.
If you want to put the element into a comment consider to move to XSLT 3.0 and use
<xsl:template match="xsd:complexType[#name='AccountsReceivableInfo_Type']/xsd:sequence/xsd:element[#ref ='SourceIncomePct']">
<xsl:comment select="serialize(.)"/>
</xsl:template>

why am I getting Invalid attribute value for 'type' in element 'element' in my webservice?

I'm making a contract first webservice so my first xds(MensajeDetails.xds) is:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://webservices.samples.blog.com" targetNamespace="http://webservices.samples.blog.com" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:element name="Mensaje" type="Mensaje"/>
<xs:complexType name="Mensaje">
<xs:sequence>
<xs:element name="IdMensajesEnviados" type="xs:long"/>
<xs:element name="CodigoEstatus" type="xs:int"/>
<xs:element name="DescripcionEstatus" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
and in my 2nd xds (MensajeDetailsServiceOperation.xds) I´ve:
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://com/blog/samples/webservices/mensajeservice" xmlns:account="http://webservices.samples.blog.com" targetNamespace="http://com/blog/samples/webservices/mensajeservice" elementFormDefault="qualified">
<xsd:import namespace="http://webservices.samples.blog.com" schemaLocation="MensajeDetails.xsd"/>
<xsd:element name="MensajeDetailsRequest">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="IdUsuario" type="xsd:long"/>
<xsd:element name="Token" type="xsd:string"/>
<xsd:element name="IdServicio" type="xsd:int"/>
<xsd:element name="Archivo" type="xsd:byte"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="MensajeDetailsResponse">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="MensajeDetails" type="mensaje:Mensaje"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
So eclipse is telling me that in my 2nd xds
s4s-att-invalid-value: Invalid attribute value for 'type' in element 'element'.
Recorded reason: UndeclaredPrefix: Cannot resolve 'mensaje:Mensaje' as a QName: the prefix 'mensaje' is not declared." in the line:
<xsd:element name="MensajeDetails" type="mensaje:Mensaje"/>
What am I doing wrong?
You have imported the namespace into your schema and have declared a namespace prefix for it, in your schema declaration your have xmlns:account="http://webservices.samples.blog.com", this binds the prefix "account" to your imported namespace.
So, either change your element to account:Mensaje or change the prefix to mensaje
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://com/blog/samples/webservices/mensajeservice"
xmlns:mensaje="http://webservices.samples.blog.com"
targetNamespace="http://com/blog/samples/webservices/mensajeservice"
elementFormDefault="qualified">

How can I debug QXmlSchema's load method?

I'm trying to load the following XML Schema with QXmlSchema, however QXmlSchema::load(const QUrl & source) always returns false. Is there any way to have Qt provide some about what actually went wrong? The schema checks out fine in several validators as far as I can tell (the w3c one provided mysterious output that looked like it passed).
<?xml version="1.0" ?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="message">
<xsd:complexType>
<xsd:choice>
<xsd:element name="login-reply">
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:enumeration value="Accepted" />
<xsd:enumeration value="Rejected" />
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name="login-request" >
<xsd:complexType>
<xsd:sequence>
<xsd:element name="username" type="xsd:string" nillable="false"/>
<xsd:element name="password" type="xsd:string" nillable="false"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="logout-request">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="username" type="xsd:string" nillable="false"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="logout-reply">
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:enumeration value="Accepted" />
<xsd:enumeration value="Rejected" />
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name="tasklist-request" />
<xsd:element name="tasklist-reply">
<xsd:complexType>
<xsd:sequence minOccurs="1">
<xsd:element name="package" minOccurs="1" nillable="false">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="taskgroup" minOccurs="1" nillable="false">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="id" type="xsd:integer" minOccurs="1" />
<xsd:element name="task" type="xsd:string" minOccurs="1" />
</xsd:sequence>
<xsd:attribute name="id" type="xsd:integer" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
</xsd:sequence>
<xsd:attribute name="id" type="xsd:integer" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="starttask-request">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="task-id" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="starttask-reply">
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:enumeration value="Accepted" />
<xsd:enumeration value="Rejected" />
</xsd:restriction>
</xsd:simpleType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
bool QXmlSchema::load() itself returns only boolean result that is not really useful for debugging. But there this is more better way to get more appropriate error message.
You could use method void QXmlSchema::setMessageHandler(QAbstractMessageHandler *handler).
Here is example from my project.
First subclassing QAbstractMessageHandler
class MessageHandler : public QAbstractMessageHandler
{
public:
MessageHandler()
: QAbstractMessageHandler(),
m_messageType(QtMsgType()),
m_description(),
m_sourceLocation(QSourceLocation())
{}
QString statusMessage() const
{
return m_description;
}
qint64 line() const
{
return m_sourceLocation.line();
}
qint64 column() const
{
return m_sourceLocation.column();
}
protected:
virtual void handleMessage(QtMsgType type,
const QString &description,
const QUrl &identifier,
const QSourceLocation &sourceLocation) Q_DECL_OVERRIDE
{
Q_UNUSED(type);
Q_UNUSED(identifier);
m_messageType = type;
m_description = description;
m_sourceLocation = sourceLocation;
}
private:
QtMsgType m_messageType;
QString m_description;
QSourceLocation m_sourceLocation;
};
Then before loading set message handler.
QFile file("myschema.xsd");
file.open(QIODevice::ReadOnly);
MessageHandler messageHandler;
QXmlSchema sch;
sch.setMessageHandler(&messageHandler);
if (sch.load(&file, QUrl::fromLocalFile(file.fileName()))==false)
{
QString error = messageHandler.statusMessage();
qint64 line = messageHandler.line();
qint64 column = messageHandler.column();
/*Do what need if error*/
}
bool QXmlSchema::load() returns false on multiple conditions according to this source documentation
So the answer to my question: No, there is no way to get an error message from Qts parser per Qt 4.7.3 and there is no way via Qts APIs to differentiate between an I/O error and a schema error, since load returns false on both.