VBScript "GenerateXSD" command creates empty "include" elements - xsd

Is there a way to use VBScript or JScript in Enterprise Architect to correctly generate "include" elements? It seems there are no options analogous to the "Use relative-path to reference XSDs" option that is present in the "Generate XML Schema" GUI. Hence, "include" elements are empty.
I have two packages:
"Primitives", which contains a custom "BinaryContent" class
"Event", which contains an "Event" class, which has an element of type "BinaryContent". So "Event" references "Primitives".
Using the "Generate XML Schema" GUI and ticking the "Use relative-path to reference XSDs" option, Event.xsd generates fine:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:include schemaLocation="Primitives.xsd"/>
<xs:complexType name="Event">
<xs:sequence>
<xs:element name="list" type="BinaryContent" minOccurs="1" maxOccurs="100"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
But the VBScript GenerateXSD command:
project.GenerateXSD currentPackage.PackageGUID, "D:/EA_Test/schema/" + currentPackage.Name + ".xsd", "UTF-8", ""
generates an empty "include" element:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:include/>
<xs:complexType name="Event">
<xs:sequence>
<xs:element name="list" type="BinaryContent" minOccurs="1" maxOccurs="100"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
According to the Enterprise Architect documentation, the only option supported on the GenerateXSD command that would go in the empty quotes above is GenGlobalElement, which is not the option I want. What am I missing?

Related

Use of the schema-element node test in XSD 1.1's assert test

I am trying to design a XML schema where a certain element may alternatively hold either a single element belonging to a substitution group or a collection of certain elements which I want to be free-order (like in "all").
Due to the limitations on the "all" type of groups I cannot nest it into a "choice", so I tried a design which is similar to the following:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning" elementFormDefault="qualified" attributeFormDefault="unqualified" vc:minVersion="1.1">
<xs:element name="X" abstract="true"/>
<xs:element name="X1" substitutionGroup="X"/>
<xs:element name="X2" substitutionGroup="X"/>
<xs:element name="Y">
<xs:complexType>
<xs:all>
<xs:element ref="X" minOccurs="0"/>
<xs:element name="Z1" minOccurs="0" type="xs:string"/>
<xs:element name="Z2" minOccurs="0" type="xs:string"/>
<xs:element name="Z3" minOccurs="0" type="xs:string"/>
</xs:all>
<xs:assert test="not(schema-element(X)) or not(Z1 or Z2 or Z3)"/>
</xs:complexType>
</xs:element>
</xs:schema>
When the schema file is validated, I get the following error:
File C:\whereabouts\xsd-assertion-problem.xsd is not valid.
Assertion 'not(schema-element(X)) or not(Z)' is no valid XPath 2.0 expression.
Error location: xs:schema / xs:element / xs:complexType / xs:assert
Details
XPST0008: Element name not found in static context's in-scope element declarations
as-props-correct.2: Assertion 'not(schema-element(X)) or not(Z)' is no valid XPath 2.0 expression.
The question is: what is wrong here and how to fix it? When I read (https://www.w3.org/TR/xpath-31/#ERRXPST0008)[the description of XPath error condition], it explicitly excludes "an ElementName in an ElementTest", which should be the case here, so static analysis should not fail here. Or am I wrong?
Note that the substitution group for X is open for extension and finding all locations where references to X are made may be difficult, that's why I strongly prefer to use a schema-element-based test.
On the other hand, while writing Z1 or Z2 or Z3 is also cumbersome, these elements are local, so this solution is more or less acceptable. Of course, if there are better ideas, they are welcome!
Just in case, I rely on the Altova engine.

How can I define an XML schema element that allows either base64 content or an xop:Include element?

I have a XML schema that defines an element that may be either base64 text or an xop:Include element. Currently, this is defined as a base64Binary type:
<xs:element name="PackageBinary" type="xs:base64Binary" minOccurs="1" maxOccurs="1"/>
When I insert the xop:Include element instead, it looks like this:
<PackageBinary>
<xop:Include xmlns:xop="http://www.w3.org/2004/08/xop/include" href="http://google.com/data.bin" />
</PackageBinary>
But this gives an XML validation error (I'm using .NET validator):
The element 'mds:xml-schema:soap11:PackageBinary' cannot contain child
element 'http://www.w3.org/2004/08/xop/include:Include' because the
parent element's content model is text only.
This makes sense because it's not base64 content, but I thought this was common practice...? Is there any way to support this in the schema? (We have existing product that supports this syntax but we are adding validation now.)
The best I could come up with was to create a complex type that allowed any tags but was also tagged as "mixed" so it allowed text. This doesn't explicitly declare the content as base64, but it does let it pass validation.
<xs:complexType name="PackageBinaryInner" mixed="true">
<xs:sequence>
<xs:any minOccurs="0" maxOccurs="1"/>
</xs:sequence>
</xs:complexType>
<xs:element name="PackageBinary" type="PackageBinaryInner" minOccurs="1" maxOccurs="1"/>
The solution I've found is like this:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema targetNamespace="http://example.org"
elementFormDefault="qualified"
xmlns="http://example.org"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xop="http://www.w3.org/2004/08/xop/include">
<xs:import namespace="http://www.w3.org/2004/08/xop/include"
schemaLocation="http://www.w3.org/2004/08/xop/include"/>
<xs:complexType name="PackageBinary" mixed="true">
<xs:all>
<xs:element ref="xop:Include"/>
</xs:all>
</xs:complexType>
I saw this in an xml document that appeared to allow validation - basically the attribute xmlns:xop="..." did the trick:
<SomeElement xmlns:xop="http://www.w3.org/2004/08/xop/include/" id="465390" type="html">
<SomeElementSummaryURL>https://file.someurl.com/SomeImage.html</SomeElementSummaryURL>
<xop:Include href="cid:1111111#someurl.com"/>
</SomeElement >

How do I define one-to-many relationships across different XSD Files, and why does xs:extends not work in this situation?

I have been developing some xml schema files over the past few days, and learned of a specific element to extend simpletypes and complextype elements.
I am currently using the visual studio 2012 professional edition, and I am currently testing relationships of XSD files (I daresay parent-child relationships , or one to many relationships) between these files, for example (I am using objects from Google DFA API):
RichMediaAsset
∟ RichMediaExpandingHtmlAsset
∟ RichMediaExpandingHtmlAsset
∟ RichMediaFloatingHtmlAsset
...
All these classes "extend" or "Inherit" from RichMediaAsset (which is the base, or abstract). I have defined RichMediaAsset as the following in XSD
<?xml version="1.0" standalone="yes"?>
<xs:schema id="RedirectCreativeBase" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<!-- simpleTypes=primitive -->
<!-- extBooleanMethodPrefix=is -->
<xs:complexType name="RichMediaAssetWrapper" abstract="true">
<xs:sequence>
<xs:element name="fileName" type="xs:string" minOccurs="0" />
<xs:element name="fileSize" type="xs:int" minOccurs="0" />
<xs:element name="id" type="xs:long" minOccurs="0" />
<xs:element name="parentAssetId" type="xs:long" minOccurs="0" />
<xs:element name="type" type="xs:string" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:schema>
I have defined the second file, RichMediaExpandingHtmlAsset as follows:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="RichMediaExpandingHtmlAssetWrapper" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:include schemaLocation="./RichMediaAsset.xsd"/>
<xs:complexType name="RichMediaExpandingHtmlAssetWrapper" abstract="false" >
<xs:extension base="RichMediaAssetWrapper"> <!-- Not happy here -->
<xs:sequence>
<!-- content to be included,extending RichMediaAsset's complex type called RichMediaAssetWrapper -->
</xs:sequence>
</xs:extension>
</xs:complexType>
</xs:schema>
The part which I mentioned VS2012 is not happy with is defined as follows:
Warning 1 The 'http://www.w3.org/2001/XMLSchema:extension' element is not supported in this context. C:\eclipse\Workspace\aem_adservices_google_dfa\aem.adservices.google.dfa\xsd\Creative\RichMediaExpandingHtmlAsset.xsd 5 6 Miscellaneous Files
Warning 2 The element 'complexType' in namespace 'http://www.w3.org/2001/XMLSchema' has invalid child element 'extension' in namespace 'http://www.w3.org/2001/XMLSchema'. List of possible elements expected: 'annotation, simpleContent, complexContent, group, all, choice, sequence, attribute, attributeGroup, anyAttribute' in namespace 'http://www.w3.org/2001/XMLSchema'. C:\eclipse\Workspace\aem_adservices_google_dfa\aem.adservices.google.dfa\xsd\Creative\RichMediaExpandingHtmlAsset.xsd 5 6 Miscellaneous Files
The question now: Is this a possible bug of 2012, have I made an error, is this simply not supported (even though I checked the usage examples at w3schools.com), or is there better ways for me to define the one to many relationships?
I found the issue with my XSD. It was in fact missing a tag. In these cases, xs:complexContent or xs:simpleContent must be defined in order to define extensions or restrictions on a complex/simple type respectively that contains mixed content or elements only.
Here is my solution, and the errors in my code also disappeared.
<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="RichMediaExpandingHtmlAssetWrapper" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:include schemaLocation="./RichMediaAsset.xsd"/>
<xs:complexType name="RichMediaExpandingHtmlAssetWrapper" abstract="false" >
<xs:complexContent>
<xs:extension base="RichMediaAssetWrapper">
<xs:sequence>
...
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:schema>
Sources: ComplexContent; SimpleContent

Generate Nested Types instead of Global Types with xsd.exe

Using xsd.exe in a C# class, is there a way to produce a xsd file with Nested Type, instead of Global Types?
I want to use this xsd file, with SSIS - Sql Server Integration Services, and look SSIS is not reading my xsd very well.
I want to generate the xsd like this, with Nested Types :
<?xml version="1.0" encoding="utf-8"?>
<xs:schema targetNamespace="http://tempuri.org/XMLSchema.xsd" elementFormDefault="qualified" xmlns="http://tempuri.org/XMLSchema.xsd" xmlns:mstns="http://tempuri.org/XMLSchema.xsd" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="Country">
<xs:complexType>
<xs:sequence>
<xs:element name="City">
<xs:complexType>
<xs:sequence>
<xs:element name="CityName" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="CoutryName" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
but xsd.exe produce this , with Global Types, and SSIS don't read it. I need to change this xsd manually to be like above.
<?xml version="1.0" encoding="utf-8"?>
<xs:schema targetNamespace="http://tempuri.org/XMLSchema.xsd" elementFormDefault="qualified" xmlns="http://tempuri.org/XMLSchema.xsd" xmlns:mstns="http://tempuri.org/XMLSchema.xsd" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="Country">
<xs:complexType>
<xs:sequence>
<xs:element name="City" type="City">
</xs:element>
<xs:element name="CoutryName" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="City">
<xs:sequence>
<xs:element name="CityName" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:schema>
Any suggestion? Or other tool that I can use.
Thanks a lot.
I'll further assume that not "very well" means you're not seeing CountryName in your XML Source output.
The documentation on MSDN is a good reading, although in my opinion it fails to describe why you would encounter the behavior you see.
I believe that it has to do with the way XML Source outputs are being determined. SSIS infers a data set from the XML structure; the top level entity, that corresponds to the root element, is not mapped to an output, so all the attributes associated with it, in your case CountryName, will not show up.
The easiest way to prove it, is to add another root element that wraps your Country (equivalent to having a dummy "root" class that has a Country-type property).
<xs:element name="root">
<xs:complexType>
<xs:sequence>
<xs:element ref="Country"/>
</xs:sequence>
</xs:complexType>
</xs:element>
If you add the above schema fragment to your schema, you should get your expected results. At the beginning I thought that it has to do with the issue described here; while you can still use the tool to visualize the data set as described by the MSDN link above, in your case, the authoring style you suggested (basically a russian-doll) can't change the outcome.

What is wrong with extending an XML Schema type using xs:all?

<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns="http://tempuri.org/ServiceDescription.xsd" xmlns:mstns="http://tempuri.org/ServiceDescription.xsd" xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://tempuri.org/ServiceDescription.xsd" elementFormDefault="qualified" id="ServiceDescription">
<xs:element name="Template">
<xs:complexType>
<xs:complexContent>
<xs:extension base="ServiceType">
<xs:all>
<xs:element name="TemplateCode" type="xs:string"/>
</xs:all>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:element>
<xs:complexType name="ServiceType">
<xs:all>
<xs:element name="ServiceCode" type="xs:string"/>
</xs:all>
</xs:complexType>
</xs:schema>
When I try to save this in XMLSpy it tells me
An 'all' model group is neither allowed in complex type definition 'mstns:ServiceType' nor in its extension '{anonymous}'.
Clicking Details gives a link to a paragraph in XML Schema specification which I do not understand.
Added: Ah, yes, forgot to mention - the line of error is this one:
<xs:element name="TemplateCode" type="xs:string"/>
The problem is you can't have all if you're extending another type. As far as XML knows the parent type might have a sequence model and since XML forbids putting an all group inside of a sequence group (since that would destroy the sequence group's ordering) then XML also forbids putting an all group in an extension of a complex type. You could use sequence instead of all for both though and you'd be fine.

Resources