Use XML Schema to extend an element with attributes rather than a complexType - xsd

So I found this post which is very similar to what I want to achieve, but I can't quite figure out if it's not possible to do what I am attempting, or if I'm just missing something...
Use XML Schema to extend an element rather than a complexType
The gist is that I have an XSD that contains a defined Element. I would prefer not to edit this original xsd file. Is there any way for me to extend the Element so that I also can add my own attributes, "attributeC"?
The other post creates a new complexType of fooType, and places the element inside of it, and extends fooType to contain more elements. By doing so, they are able to achieve an Element that contains fooElement, and two other added elements. The issue is that I'd like to add to the Element itself, not add to the element at the same level.
XSD1
<xs:schema xmlns:bas="http://www.base.com"
xmlns="https://www.adding.com"
attributeFormDefault="qualified"
elementFormDefault="qualified"
targetNamespace="https://www.adding.com"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:import schemaLocation="XSD2.xsd" namespace="http://www.base.com" />
<xs:complexType name="FileSpecType">
<xs:sequence>
<xs:element ref="bas:FileSpec"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="FullFileSpecType">
<xs:complexContent mixed="false">
<xs:extension base="FileSpecType">
<xs:attribute name="attributeC" type="xs:string" />
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:element name="FileSpec" type="FileSpecType" />
This code ends up generating a new FileSpec
<FileSpec AttributeC="attCval" />>
<bas:FileSpec/>
</FileSpec>
What I want to achieve is more like...
<bas:FileSpec AttributeA="attAval" AttributeB="attBval" AttributeC="attCval/>
Can anybody point me in the right direction to solve my issues?
I'm thinking I could define my own dataType=FileSpec and add my own reference to external attributes, but that'd require manually copying over each attribute that exists in my original XSD2 FileSpec so I'd prefer to avoid that if possible. Then I think I could take that new FileSpec that I created and redefine the older FileSpec with it. Is this possible to do? It sounds like a lot of work that must have a simpler solution.

Its somewhat unclear what you are trying to do, if this does not cover it, please post the schema you are including as well as the XML you are trying to produce including the containing element.
You can extend an existing xs:complexType like this.
<?xml version="1.0" encoding="utf-8" ?>
<!--Created with Liquid Studio 2020 (https://www.liquid-technologies.com)-->
<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:complexType name="BaseType">
<xs:attribute name="attributeA" type="xs:string" />
</xs:complexType>
<xs:complexType name="ExtendedType">
<xs:complexContent>
<xs:extension base="BaseType">
<xs:attribute name="attributeB" />
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:element name="RootElm">
<xs:complexType>
<xs:sequence>
<xs:element name="BaseElm" type="BaseType" />
<xs:element name="ExtendedElm" type="ExtendedType" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
This allows you to produce XML that looks like this
<?xml version="1.0" encoding="utf-8"?>
<!-- Created with Liquid Studio 2020 (https://www.liquid-technologies.com) -->
<RootElm xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<BaseElm attributeA="XX" />
<ExtendedElm attributeA="YY" attributeB="ZZ" />
</RootElm>
There is another way to make use of the ExtendedType when ever its valid to use a BaseType
<?xml version="1.0" encoding="utf-8"?>
<!-- Created with Liquid Studio 2020 (https://www.liquid-technologies.com) -->
<RootElm xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<BaseElm xsi:type="ExtendedType" attributeB="XX" attributeA="YY" />
<ExtendedElm attributeA="XX" attributeB="YY" />
</RootElm>
Notice the xsi:type="ExtendedType" in the BaseElm, this tells the XML processor that this element actually contains data for the ExtendedType.

Related

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.

Need help with (recursive) xsd group

I have this xsd:
<?xml version="1.0" encoding="utf-8" ?>
<xs:schema xmlns="http://myschema.com/schema"
targetNamespace="http://myschema.com/schema"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:complexType name="aType" mixed="true">
<xs:group ref="aElements" minOccurs="0" maxOccurs="unbounded"/>
</xs:complexType>
<xs:group name="aElements">
<xs:choice>
<xs:element name="a" type="aType"/>
</xs:choice>
</xs:group>
<xs:element name="b">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:group ref="aElements"/>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>
and I try to validate this xml document against it:
<?xml version="1.0" encoding="utf-8" ?>
<b xmlns="http://myschema.com/schema">
<a/>
</b>
However, Visual Studio 2008's xml validator complains about the <a> element:
The element 'b' in namespace 'http://myschema.com/schema' has invalid child element 'a' in namespace 'http://myschema.com/schema'. List of possible elements expected: 'a'.
What is the problem?
Edit: Oops, when dumbing down the example I caused forgot to make the element optional inside the element, causing infinite recursion. The problem is still there with this mod, though.
ANSWER: The answer was that the xs:schema tag should include the elementFormDefault="qualified" attribute.
you define aElements with aType, and aType with aElements. i'm not an xsd expert, but how is that supposed to work?
You could make your life much easier using an editor for XSD development. We've been using Liquid XML Studio for ages, it makes life much easer.

Resources