Why won't this Schema validate this XML file? - validation

The XML file:
<Lista count="3">
<Pelicula nombre="Jurasic Park 3">
<Genero>Drama</Genero>
<Director sexo="M">Esteven Spielberg</Director>
<Temporada>
<Anho>2002</Anho>
<Semestre>Verano</Semestre>
</Temporada>
</Pelicula>
<Pelicula nombre="Maldiciones">
<Genero>Ficcion</Genero>
<Director sexo="M">Pedro Almodovar</Director>
<Temporada>
<Anho>2002</Anho>
<Semestre>Verano</Semestre>
</Temporada>
</Pelicula>
<Pelicula nombre="Amor en New York">
<Genero>Romance</Genero>
<Director sexo="F">Katia Hertz</Director>
<Temporada>
<Anho>2002</Anho>
<Semestre>Verano</Semestre>
</Temporada>
</Pelicula>
</Lista>
And here's the XML Schema file I made, it's not working. :\
<xsd:complexType name="Lista">
<xsd:attribute name="count" type="xsd:integer" />
<xsd:complexContent>
<xsd:element name="Pelicula" type="xsd:string">
<xsd:attribute name="nombre" type="xsd:string" />
<xsd:complexType>
<xsd:sequence>
<xsd:element name="Genero" type="generoType"/>
<xsd:element name="Director" type="directorType">
<xsd:attribute name="sexo" type="sexoType"/>
</xsd:element>
</xsd:element name="Temporada">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="Anho" type="anhoType" />
<xsd:element name="Semestre" type="semestreType" />
</xsd:sequence>
</xsd:complexType>
<xsd:element></xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:complexContent>
</xsd:complexType>
<xsd:simpleType name="sexoType">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="F"/>
<xsd:enumeration value="M"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="directorType">
<xsd:restriction base="xsd:string" />
</xsd:simpleType>
<xsd:simpleType name="generoType">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="Drama"/>
<xsd:enumeration value="Accion"/>
<xsd:enumeration value="Romance"/>
<xsd:enumeration value="Ficcion"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="semestreType">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="Verano"/>
<xsd:enumeration value="Invierno"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="anhoType">
<xsd:restriction base="xsd:integer">
<xsd:minInclusive value="1970"/>
<xsd:maxInclusive value="2020"/>
</xsd:restriction>
</xsd:simpleType>

Try declaring and using your types separately. This makes the XSD a bit longer, but less nested and more readable (and more reusable, too):
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- document element -->
<xs:element name="Lista" type="listaType" />
<!-- type definitions -->
<xs:complexType name="listaType">
<xs:sequence>
<xs:element name="Pelicula" type="peliculaType" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
<xs:attribute name="count" type="countType" />
</xs:complexType>
<xs:complexType name="peliculaType">
<xs:all>
<xs:element name="Genero" type="generoType" />
<xs:element name="Director" type="directorType" />
<xs:element name="Temporada" type="temporadaType" />
</xs:all>
<xs:attribute name="nombre" type="xs:string" />
</xs:complexType>
<xs:complexType name="directorType">
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="sexo" type="sexoType" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:complexType name="temporadaType">
<xs:all>
<xs:element name="Anho" type="anhoType" />
<xs:element name="Semestre" type="semestreType" />
</xs:all>
</xs:complexType>
<xs:simpleType name="sexoType">
<xs:restriction base="xs:string">
<xs:enumeration value="F" />
<xs:enumeration value="M" />
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="generoType">
<xs:restriction base="xs:string">
<xs:enumeration value="Drama" />
<xs:enumeration value="Accion" />
<xs:enumeration value="Romance" />
<xs:enumeration value="Ficcion" />
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="semestreType">
<xs:restriction base="xs:string">
<xs:enumeration value="Verano" />
<xs:enumeration value="Invierno" />
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="anhoType">
<xs:restriction base="xs:integer">
<xs:minInclusive value="1970" />
<xs:maxInclusive value="2020" />
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="countType">
<xs:restriction base="xs:integer">
<xs:minInclusive value="0" />
</xs:restriction>
</xs:simpleType>
</xs:schema>
The above validates your input XML.
Note that:
The convention for the XML Schema namespace prefix is xs (AFAIK - you can still go on and use xsd if you prefer).
The count attribute is really unnecessary, since the count can a) easily be calculated and b) there is a risk of something going wrong when the count attribute value and the actual count differ for some reason. Things that are derivable from the data should never be part of the data.
Oh, and to answer your initial question (why does mine not work):
You never declare an actual document element ("Lista"), you just declare its type. Compare with my solution.
In the complexType name="Lista":
attribute cannot be the first child of a complex type. Attributes must be declared after everything else.
complexContent cannot contain element.
in fact, you don't need a complexContent at all - just use a sequence instead.
In element name="Pelicula":
The type attribute is illegal when you declare a complexType within.
In the complexType for "Pelicula":
Again, attributes last.
Don't use a sequence unless you want to make any other order of children illegal. In this type of document I would guess child order is irrelevant.
In element name="Director":
You can't declare any attributes since when you already declared a type. Include the sexo attribute in the directorType
In simpleType name="directorType":
This should in reality be a complexType containing simpleContent with an extension. This way you can include the sexo attribute
Your XSD isn't even well formed XML.
Your XML iswas not well-formed, either. I have fixed it to be able to test in the first place.
P.S.: There is enough XSD documentation freely available to fix many of the basic problems you've had. There are XSD validators on the Net that help you by telling you what constructs are illegal. Knowing everything is absolutely not necessary, but a little reading + trial and error would have helped. ;-)

For a start:
<Semestre>Verano<Semestre>
...doesn't look well-formed.

Related

XSD - How to validate an attribute value of different strings with different custom validations?

Greetings fellow stackoverflowians,
Work is asking for XML validation by using XSD and I'm the lucky one who was selected to spear head this effort (I have no XSD experience). I'm currently learning XSD so I apologize if I'm using wrong XSD lingo.
I was able to create a XSD to blankly validate the XML, but now custom validation for specific elements has been requested. I'm currently stuck on how to validate each string in the second attribute of element property that requires each string to be checked against different validation rules.
This is my first time asking a question, but have enjoyed the shared knowledge in stackoverflow for years. Any additional feedback on proper question asking is appreciate and I sincerely appreciate the help figuring out this problem.
I'm using version 1.0, but willing to bump up to version 1.1 if needed
Here is part of the XML that I have to validate with custom validation
<properties>
<property name="description" value="long reference string"></property>
<property name="passfailcriteria" value="long BDD string"></property>
<property name="automationpath" value="url"></property>
<property name="passfailcriteria" value="stuff, stuff, stuff"></property>
<property name="teststatus" value="ready"></property>
<property name="autocandidacy" value="automated"></property>
</properties>
Here is my current attempt at XSD validation
<xs:element name="properties">
<xs:complexType>
<xs:sequence>
<xs:element ref="property" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="property">
<xs:complexType>
<xs:attribute name="name" type="property-names" use="required"/>
<xs:attribute name="value" type="property-values" use="required"/>
</xs:complexType>
</xs:element>
<xs:simpleType name="property-names">
<xs:restriction base="xs:string">
<xs:enumeration value="autocandidacy"/>
<xs:enumeration value="automationpath"/>
<xs:enumeration value="description"/>
<xs:enumeration value="passfailcriteria"/>
<xs:enumeration value="ptes_req"/>
<xs:enumeration value="tags"/>
<xs:enumeration value="teststatus"/>
<xs:enumeration value="verificationmentod"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="property-values">
<xs:sequence minOccurs="0" maxOccurs="unbounded">
<xs:element name="autocandidacy" type="autocandidacy"/>
<xs:element name="automationpath" type="xs:string"/>
<xs:element name="description" type="xs:string"/>
<xs:element name="passfailcriteria" type="xs:string"/>
<xs:element name="ptes_req" type="xs:string"/>
<xs:element name="tags" type="tags"/>
<xs:element name="teststatus" type="teststatus"/>
<xs:element name="verificationmentod" type="verificationmentod"/>
</xs:sequence>
</xs:complexType>
<!-- Verification Mentod-->
<!-- List of values acceptable for the property Verification Method -->
<xs:simpleType name="verificationmentod">
<xs:restriction base="xs:string">
<xs:enumeration value="Demonstration"/>
<xs:enumeration value="Exam of Children"/>
<xs:enumeration value="Test"/>
<xs:enumeration value="Analysis"/>
</xs:restriction>
</xs:simpleType>
<!-- Auto Candidacy-->
<!-- List of values acceptable for the property Auto Candidacy -->
<xs:simpleType name="autocandidacy">
<xs:restriction base="xs:string">
<xs:enumeration value="AIP"/>
<xs:enumeration value="automated"/>
<xs:enumeration value="No"/>
<xs:enumeration value="Ready"/>
<xs:enumeration value="Yes"/>
</xs:restriction>
</xs:simpleType>
<!-- Test Status Value -->
<!-- List of values acceptable for the property teststatus -->
<xs:simpleType name="teststatus">
<xs:restriction base="xs:string">
<xs:enumeration value="WIP"/>
<xs:enumeration value="Ready for Review"/>
<xs:enumeration value="In Review"/>
<xs:enumeration value="Ready"/>
<xs:enumeration value="Repair"/>
</xs:restriction>
</xs:simpleType>
<!-- tags -->
<!-- Checks that the string is a comma seperated value -->
<xs:simpleType name="tags" >
<xs:restriction base="xs:string">
<xs:pattern value="[a-zA-Z][a-zA-Z0-9]*(\s*,\s*[a-zA-Z][a-zA-Z0-9]*){0,10}" />
</xs:restriction>
</xs:simpleType>
I broke each string that needs a custom validation into it's own block, put all required values into a block property-values and tried to reference that in the attribute that needs the validation <xs:attribute name="value" type="property-values" use="required"/>.
I can't seem to figure out how to validate the strings in attribute name="name" with the related attribute name="value" that uses the custom validation I built for that string.
example:
Tags is input in the property name
So the value input to the property value should be validated by the tags block I created to make sure the string meets the criteria.

Where is the schema of `child-resources` specified?

I'm trying to find where the schema of the result of a child-resources query is specified in the xsd. It's clearly not a primitiveContent (specified in responsePrimitive) because that doesn't contain the named child-resources arrays.
I think this is in the CDT-responsePrimitive-v.xsd file. In Resourcewrapper you have "m2m:sg_regularResource":
<xs:complexType name="resourceWrapper">
<xs:sequence>
<xs:choice minOccurs="1" maxOccurs="1">
...
<xs:element ref="m2m:sg_regularResource" />
...
</xs:choice>
<xs:element name="URI" type="xs:anyURI" />
</xs:sequence>
</xs:complexType>
In any of the resources that is a "m2m:sg_regularResource" you can find a section like this that allows for "included" child resources:
...
<!-- Child Resources -->
<xs:choice minOccurs="0" maxOccurs="1">
<xs:element name="childResource" type="m2m:childResourceRef" minOccurs="1" maxOccurs="unbounded" />
<xs:choice minOccurs="1" maxOccurs="unbounded">
<xs:element ref="m2m:aResourceType" />
<xs:element ref="m2m:anotherResourceType" />
</xs:choice>
</xs:choice>
...

Using namespaces in Oracle XMLTable query returns no results (works without them)

Querying a very large set of XML data in Oracle 11g (datafeeds, 65k rows), and I need to match against existing users in a table with ~240k records. We store the XML data in a binary XML column and use an xmltable() query, and we've registered a schema that is valid and that the XML data we're sending validates against (from within Oracle).
For testing purposes, I'm using a dozen records and executing just the subset query:
select dfids.*
from gsu.datafeed_xmldata gdfxml,
xmltable('/UserIdentifications/OrgIds/OrgId'
passing gdfxml.xml_data_binary
columns LEGAL_ORG_ID varchar2(32) path 'LegalOrg',
LOCAL_ID varchar2(32) path 'LocalId') dfids
This query returns the dozen records quickly, with no problem. The 65k records take about 16 minutes. So we wrote this:
select dfids.*
from gsu.datafeed_xmldata gdfxml,
xmltable(xmlnamespaces('http://xmlns.te.com/infosec/useridentifications_binary3.xsd' as "ids"),
'/ids:UserIdentifications/ids:OrgIds/ids:OrgId'
passing gdfxml.xml_data_binary
columns LEGAL_ORG_ID varchar2(32) path 'ids:LegalOrg',
LOCAL_ID varchar2(32) path 'ids:LocalId') dfids
We now get 0 records. All variations of the paths and columns, with prefixes and without, with different prefixes, using the schema URL, using the qualified schema URL, re-registering the schema, recreating the table... nothing works. It's been three days of digging through a landfill of slightly related answers and solutions, none of which helped. I feel like this should be a simple answer - what am I doing wrong?
Technical Details
Table that holds the xml data:
create table xxx.DATAFEED_XMLDATA
(
xml_data_binary SYS.XMLTYPE
)
xmltype xml_data_binary store as binary xml
tablespace xxx_DATA_A
pctfree 10
initrans 1
maxtrans 255
storage
(
initial 32M
next 4M
minextents 1
maxextents unlimited
);
A minimal set of xml records (there are three ways of uniquely identifying a user – don't ask, it's a sore subject):
<?xml version="1.0" encoding="utf-8"?>
<UserIdentifications>
<UserIds>
<UserId>
<Id>ABC12345</Id>
</UserId>
<UserId>
<Id>DEF67890</Id>
</UserId>
</UserIds>
<PerNrs>
<PerNr>
<Id>00987654</Id>
</PerNr>
<PerNr>
<Id>00341256</Id>
</PerNr>
</PerNrs>
<OrgIds>
<OrgId>
<LegalOrg>0420</LegalOrg>
<LocalId>11432</LocalId>
</OrgId>
<OrgId>
<LegalOrg>0619</LegalOrg>
<LocalId>334266</LocalId>
</OrgId>
</OrgIds>
</UserIdentifications>
Schema details:
select *
from sys.user_xml_schemas;
http://xmlns.te.com/infosec/useridentifications_binary3.xsd
http://xmlns.oracle.com/xdb/schemas/xxx/xmlns.te.com/infosec/useridentifications_binary3.xsd (qualified)
local = yes
hier_type = contents
binary = yes
The schema itself (as registered, pulled from the above query):
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:oraxdb="http://xmlns.oracle.com/xdb"
id="UserIdentificationsSchema" oraxdb:flags="2122017"
oraxdb:schemaURL="http://xmlns.te.com/infosec/useridentifications_binary3.xsd"
oraxdb:schemaOwner="GSU_SOURCE" oraxdb:numProps="11"
xmlns:csx="http://xmlns.oracle.com/2004/CSX">
<xs:element name="UserIdentifications"
xmlns:csx="http://xmlns.oracle.com/2004/CSX"
csx:propertyID="2831" oraxdb:global="true" oraxdb:memType="258">
<xs:complexType>
<xs:annotation>
<xs:appinfo>
<csx:kidList xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xdb="http://xmlns.oracle.com/xdb">
<csx:kid csx:propertyID="2823" kidNum="1"></csx:kid>
<csx:kid csx:propertyID="2826" kidNum="2"></csx:kid>
<csx:kid csx:propertyID="2830" kidNum="3"></csx:kid>
</csx:kidList>
</xs:appinfo>
</xs:annotation>
<xs:all minOccurs="0" maxOccurs="1">
<xs:element name="UserIds" csx:propertyID="2823"
oraxdb:global="false" oraxdb:memType="258"
oraxdb:MemInline="false" oraxdb:SQLInline="true"
oraxdb:JavaInline="false">
<xs:complexType>
<xs:annotation>
<xs:appinfo>
<csx:kidList xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xdb="http://xmlns.oracle.com/xdb">
<csx:kid csx:propertyID="2822" kidNum="1">
</csx:kid>
</csx:kidList>
</xs:appinfo>
</xs:annotation>
<xs:sequence minOccurs="0" maxOccurs="unbounded">
<xs:element name="UserId" csx:propertyID="2822"
oraxdb:global="false" oraxdb:memType="258"
oraxdb:MemInline="false" oraxdb:SQLInline="true"
oraxdb:JavaInline="false">
<xs:complexType>
<xs:annotation>
<xs:appinfo>
<csx:kidList xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xdb="http://xmlns.oracle.com/xdb">
<csx:kid csx:propertyID="2821" kidNum="1">
</csx:kid>
</csx:kidList>
</xs:appinfo>
</xs:annotation>
<xs:all>
<xs:element name="Id" csx:propertyID="2821"
oraxdb:global="false" csx:encodingType="string"
oraxdb:memType="1" oraxdb:MemInline="true"
oraxdb:SQLInline="true"
oraxdb:JavaInline="true">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:whiteSpace value="collapse">
</xs:whiteSpace>
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:all>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="PerNrs" csx:propertyID="2826"
oraxdb:global="false" oraxdb:memType="258"
oraxdb:MemInline="false" oraxdb:SQLInline="true"
oraxdb:JavaInline="false">
<xs:complexType>
<xs:annotation>
<xs:appinfo>
<csx:kidList xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xdb="http://xmlns.oracle.com/xdb">
<csx:kid csx:propertyID="2825" kidNum="1">
</csx:kid>
</csx:kidList>
</xs:appinfo>
</xs:annotation>
<xs:sequence minOccurs="0" maxOccurs="unbounded">
<xs:element name="PerNr" csx:propertyID="2825"
oraxdb:global="false" oraxdb:memType="258"
oraxdb:MemInline="false" oraxdb:SQLInline="true"
oraxdb:JavaInline="false">
<xs:complexType>
<xs:annotation>
<xs:appinfo>
<csx:kidList xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xdb="http://xmlns.oracle.com/xdb">
<csx:kid csx:propertyID="2824" kidNum="1">
</csx:kid>
</csx:kidList>
</xs:appinfo>
</xs:annotation>
<xs:all>
<xs:element name="Id" csx:propertyID="2824"
oraxdb:global="false" csx:encodingType="string"
oraxdb:memType="1" oraxdb:MemInline="true"
oraxdb:SQLInline="true"
oraxdb:JavaInline="true">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:whiteSpace value="collapse">
</xs:whiteSpace>
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:all>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="OrgIds" csx:propertyID="2830"
oraxdb:global="false" oraxdb:memType="258"
oraxdb:MemInline="false" oraxdb:SQLInline="true"
oraxdb:JavaInline="false">
<xs:complexType>
<xs:annotation>
<xs:appinfo>
<csx:kidList xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xdb="http://xmlns.oracle.com/xdb">
<csx:kid csx:propertyID="2829" kidNum="1">
</csx:kid>
</csx:kidList>
</xs:appinfo>
</xs:annotation>
<xs:sequence minOccurs="0" maxOccurs="unbounded">
<xs:element name="OrgId" csx:propertyID="2829"
oraxdb:global="false" oraxdb:memType="258"
oraxdb:MemInline="false" oraxdb:SQLInline="true"
oraxdb:JavaInline="false">
<xs:complexType>
<xs:annotation>
<xs:appinfo>
<csx:kidList xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xdb="http://xmlns.oracle.com/xdb">
<csx:kid csx:propertyID="2827" kidNum="1">
</csx:kid>
<csx:kid csx:propertyID="2828" kidNum="2">
</csx:kid>
</csx:kidList>
</xs:appinfo>
</xs:annotation>
<xs:all>
<xs:element name="LegalOrg"
csx:propertyID="2827" oraxdb:global="false"
csx:encodingType="string" oraxdb:memType="1"
oraxdb:MemInline="true" oraxdb:SQLInline="true"
oraxdb:JavaInline="true">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:whiteSpace value="collapse">
</xs:whiteSpace>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="LocalId"
csx:propertyID="2828" oraxdb:global="false"
csx:encodingType="string" oraxdb:memType="1"
oraxdb:MemInline="true" oraxdb:SQLInline="true"
oraxdb:JavaInline="true">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:whiteSpace value="collapse">
</xs:whiteSpace>
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:all>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:all>
</xs:complexType>
</xs:element>
</xs:schema>

XSD key not in root element and complex keys

I searched for this, but can't find solution to my problem, so please don't trash this question.
We have a service with very complex XML configuration which is described by XSD. There are many rules that must be obeyed for things to run smoothly. XSD describes structure of configuration, but not the rules, which we must do now. After creating some global rules we have to do some more complex now and we encountered a problem. It seams like validator only uses key/keyref/unique from root element. I've created small XSD and XML file to illustrate that:
XSD:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema targetNamespace="http://test.org/XMLSchema.xsd"
elementFormDefault="qualified"
xmlns="http://test.org/XMLSchema.xsd"
xmlns:t="http://test.org/XMLSchema.xsd"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="Orders" type="t:OrdersList">
<xs:key name="OrderNo">
<xs:selector xpath="./t:Order" />
<xs:field xpath="#Number" />
</xs:key>
</xs:element>
<xs:complexType name="OrdersList">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" name="Order" nillable="false" type="t:Order" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="Order">
<xs:sequence>
<xs:element minOccurs="1" maxOccurs="1" name="Lines" nillable="false" type="t:OrdersLinesList" />
</xs:sequence>
<xs:attribute name="Number" use="optional" type="xs:string" />
<xs:attribute name="ClientId" use="optional" type="xs:int" />
</xs:complexType>
<xs:complexType name="OrdersLinesList">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" name="Line" nillable="false" type="t:OrderLine">
<!-- THE PROBLEM -->
<xs:key name="LineNoKey">
<xs:selector xpath="./t:Line" />
<xs:field xpath="#LineNumber" />
</xs:key>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:complexType name="OrderLine">
<xs:attribute name="LineNumber" use="optional" type="xs:string" />
<xs:attribute name="ProductId" use="optional" type="xs:int" />
<xs:attribute name="Amount" use="optional" type="xs:decimal" />
</xs:complexType>
</xs:schema>
XML:
<?xml version="1.0" encoding="utf-8"?>
<Orders xmlns="http://test.org/XMLSchema.xsd">
<Order Number="0001/5/13" ClientId="123">
<Lines>
<Line LineNumber="1" ProductId="123" Amount="4" />
<Line LineNumber="2" ProductId="124" Amount="4" />
</Lines>
</Order>
<Order Number="0002/5/13" ClientId="123">
<Lines>
<Line LineNumber="1" ProductId="123" Amount="4" />
<!-- Duplicate number - it DOES validate as expected. -->
<Line LineNumber="1" ProductId="124" Amount="4" />
</Lines>
</Order>
<!-- Duplicate number - it doesn't validate as expected. -->
<Order Number="0002/5/13" ClientId="123">
<Lines>
<Line LineNumber="1" ProductId="123" Amount="4" />
<Line LineNumber="2" ProductId="124" Amount="4" />
</Lines>
</Order>
</Orders>
I have a few questions which I can't find any sensible answer:
How to solve the above. LineNumber must be unique, but only within Order/Lines.
Is it possible to allow keyref to contain non existing virtual value (our service uses some predefined... let say things. Custom ones are defined in XML to allow extending functionality, but in most of the cases, users will use predefined ones)
Is there any way to determine if list of elements within a tag (something like Lines above) has at least one tag with attribute set to certain value. Good example would be to describe it like a list of tables with unique names, that has list of columns with unique names and at least one of the columns is a primary key.
This is the corrected constraint for Lines/Line:
<xs:complexType name="Order">
<xs:sequence>
<xs:element minOccurs="1" maxOccurs="1" name="Lines" nillable="false" type="t:OrdersLinesList">
<!-- THE PROBLEM SOLVED -->
<xs:key name="LineNoKey">
<xs:selector xpath="t:Line"/>
<xs:field xpath="#LineNumber"/>
</xs:key>
</xs:element>
</xs:sequence>
<xs:attribute name="Number" use="optional" type="xs:string"/>
<xs:attribute name="ClientId" use="optional" type="xs:int"/>
</xs:complexType>
If always helps if you can visualize your constraints, to understand the scope they act upon:
The correct diagram:
vs. the original one:
You can see that the selector rooted in the element Line is looking for yet another Line (./t:Line); and even if you fix the selector, it'll always match at most one attribute. The idea of a key is that the selector should match a set of nodes among which the field must be present and unique.
The above should take care of 1.
No.
Not based on an attribute. To stick with your parallel, for XSD 1.0 I would probably enforce an element called PrimaryKey, which should contain one or more references to names of the other columns; as if instead of using the PRIMARY KEY constraint clause in a column definition, I would enforce the use of the same at the table level.

case-insensitive key in xsd

I have an XSD embedded into an XML like this:
<Replacements>
<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="Replacements">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="Replace" />
</xs:sequence>
</xs:complexType>
<xs:key name="ReplaceKey">
<xs:selector xpath="./Replace"/>
<xs:field xpath="#old"/>
</xs:key>
</xs:element>
<xs:element name="Replace">
<xs:complexType>
<xs:attribute name="old" type="AnythingButLowerCase" use="required" />
<xs:attribute name="new" type="xs:string" use="required" />
</xs:complexType>
</xs:element>
<xs:simpleType name="AnythingButLowerCase">
<xs:restriction base="xs:string">
<xs:pattern value="[^a-z]+"/>
</xs:restriction>
</xs:simpleType>
</xs:schema>
<Replace old="A1020____9" new="A1020"/>
<Replace old="a1020____9" new="A1020"/>
</Replacements>
I've used xs:key to define a unique-key on "old" attribute of Replace elements.
my problem is I want this key to be CASE-INSENSITIVE.
I've read so many documents indicating I can use xsd functions like upper-case or translate to solve this, but if I write something like
<xs:field xpath="upper-case(#old)"/>
VS2010 gives me a warning like this:
'upper-case(#old)' is an invalid XPath for selector or field.
What is it I'm doing wrong?
Thanks :)
The correct XPath function is "upper-case", not "upper case". Just add in the hyphen.
OK!
I got that!
Using functions in an xpath for a xs:field is not allowed.
The workaround for what I was seeking is to define a simpleType and put a restriction there not allowing lower-case letters.
Something like this:
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<Replacements>
<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="Replacements">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="Replace" />
</xs:sequence>
</xs:complexType>
<xs:key name="ReplaceKey">
<xs:selector xpath="./Replace"/>
<xs:field xpath="#old"/>
</xs:key>
</xs:element>
<xs:element name="Replace">
<xs:complexType>
<xs:attribute name="old" type="AnythingButLowerCase" use="required" />
<xs:attribute name="new" type="xs:string" use="required" />
</xs:complexType>
</xs:element>
<xs:simpleType name="AnythingButLowerCase">
<xs:restriction base="xs:string">
<xs:pattern value="[^a-z]+"/>
</xs:restriction>
</xs:simpleType>
</xs:schema>
<Replace old="A1020____9" new="A1020"/>
<Replace old="a1020____9" new="A1020"/>
</Replacements>
Now this serves as what I want it to.

Resources