System.Xml.XmlSchemaSet compile () populates the included TargetNamespace schema

I have two xml schemas:
1) architectureRoot.xsd:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
  xmlns:mif="urn:hl7-org:v3/mif" 
  xmlns:v3="urn:hl7-org:v3" 
  xmlns:ex="urn:hl7-org/v3-example" 
  xmlns="urn:hl7-org:v3" 
  targetNamespace="urn:hl7-org:v3" 
  elementFormDefault="unqualified">
  <xs:include schemaLocation="datatypes-base.xsd"/>
  <xs:group name="InfrastructureRootElements">
    <xs:sequence>
      <xs:element name="realmCode" 
                  type="Norwegian_customer" 
                  minOccurs="0" 
                  maxOccurs="unbounded"/>
    </xs:sequence>
  </xs:group>
  <xs:attributeGroup name="InfrastructureRootAttributes"/>
</xs:schema>

      

2) datatypes-base.xsd

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:sch="http://www.ascc.net/xml/schematron"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"  
  elementFormDefault="unqualified">
  <xs:complexType name="customer">
    <xs:sequence>
      <xs:element name="firstname" type="xs:string"/>
      <xs:element name="lastname" type="xs:string"/>
      <xs:element name="country" type="xs:string"/>
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="Norwegian_customer">
    <xs:complexContent>
     <xs:restriction base="customer">
       <xs:sequence>
         <xs:element name="firstname" type="xs:string"/>
         <xs:element name="lastname" type="xs:string"/>
         <xs:element name="country" 
           type="xs:string" 
           fixed="Norway"/>
     </xs:sequence>
   </xs:restriction>
  </xs:complexContent>
 </xs:complexType>
</xs:schema>

      

I am using the following C # code to load the root schema including everything:

Func<XmlReader> xmlReaderFactory = () =>
                                        {
                                            XmlReaderSettings schemaReaderSettings = new XmlReaderSettings{ DtdProcessing = DtdProcessing.Parse};
                                                XmlTextReader reader = new XmlTextReader(@"InfrastructureRoot.xsd");
                                            return XmlReader.Create(reader, schemaReaderSettings);
                                        };

XmlSchema xsd = XmlSchema.Read(xmlReaderFactory(), (sender, eventArgs) => {});
XmlSchemaSet schemaSet = new XmlSchemaSet();
schemaSet.ValidationEventHandler += (sender, eventArgs) => Console.WriteLine(eventArgs.Message + " " + eventArgs.Severity);

try
{
    try
    {
        XmlReaderSettings schemaReaderSettings = new XmlReaderSettings {DtdProcessing = DtdProcessing.Parse};
        XmlReader schemaReader = XmlReader.Create(new DummyReader(), schemaReaderSettings);
        schemaSet.Add(null, schemaReader);
    }
    catch
    {
        // the only thing this code is needed is to set ProhibitDTD to false
        // there is no acceptable public way to do that
    }

    schemaSet.Add(xsd);
    schemaSet.Compile();
    XmlSchemaInclude external = ((XmlSchemaInclude)xsd.Includes[0]);
    String targetNamespace = external.Schema.TargetNamespace;
    Debug.Assert(targetNamespace == null);
}
catch{}

      

After executing "targetNamespace", the value is "urn: hl7-org: v3", which is different from the original "datatypes-base.xsd" schema and breaks validation. Can anyone help me with a solution?

+3


source to share


3 answers


We've worked with HL7v3 and CDA on BizTalk and .Net. In order for the CDA schemas to work correctly for validation and just send messages, I had to add a target space urn:hl7-org:v3

to all the "coreschemas" xsd files. After that, the validation worked and the BizTalk messages flowed.



I didn't like adding namespaces to schemas that I really don't own, but it was a decent compromise since I never changed the schemas themselves and then everything worked.

+2


source


When a schema document with an explicit target namespace (for example, your infrastructure Root.xsd) uses xs: include to include a schema document that does not specify a target namespace (for example, datatypes-base.xsd), the declarations in the second schema document are interpreted as as if their containing schema document has the same namespace as the schema document. This mechanism is sometimes referred to as chameleon include - declarations in the included schema document that take on a target namespace depending on the context.

If you want the complex types Customer and NorwegianCustomer not to be captured by the urn: hl7-org: v3 namespace, then the Root.xsd infrastructure needs to use xs: import, not xs: include, and the default namespace needs to be changed to reference type="Norwegian_customer"

a reference to {}Norwegian_customer

(that is, a qualified name with Norwegian_customer

as its local name and without a namespace) instead of being (as it is now) a reference to {urn:hl7-org:v3}Norwegian_customer

.



Xs: import imports components from a different namespace, and xs: include includes components from the same namespace. Chameleon include can be thought of as a way to make components in an included schema document in the same namespace; if it doesn't exist, xs: include in your infrastructure schema will just throw an error.

+2


source


The original issue was discovered while importing HL7v3 sources into our data storage format and exporting back to xml schema. The second schema gets the task namespace but not the default namespace, which results in a validation error. Here is the second output of the schema export:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema
 xmlns:sch="http://www.ascc.net/xml/schematron"
 xmlns="urn:hl7-org123:v3" 
 xmlns:v3="urn:hl7-org:v3"
 elementFormDefault="unqualified"
 targetNamespace="urn:hl7-org:v3"
 xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:complexType name="customer">
 <xs:sequence>
   <xs:element name="firstname" type="xs:string" />
   <xs:element name="lastname" type="xs:string" />
   <xs:element name="country" type="xs:string" />
 </xs:sequence>
</xs:complexType>
 <xs:complexType name="Norwegian_customer">
<xs:complexContent mixed="false">
  <xs:restriction base="customer">
    <xs:sequence>
      <xs:element name="firstname" type="xs:string" />
      <xs:element name="lastname" type="xs:string" />
      <xs:element fixed="Norway" name="country" type="xs:string" />
    </xs:sequence>
   </xs:restriction>
</xs:complexContent>
 </xs:complexType>
</xs:schema>

      

Validation fails due to the value of the constraint base attribute. As explained in the schematic diagram, we have two possible solutions:

  • Use a qualified value prefixed with "v3".
  • Add the default namespace "xmlns =" ​​urn: hl7-org: v3 ".
0


source







All Articles