3

我有两个 xml 架构:
1)infrastructureRoot.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) 数据类型-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>

我使用以下 C# 代码加载包含所有内容的根架构:

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{}

执行后 "targetNamespace" 的值等于 "urn:hl7-org:v3" ,这与原始模式 "datatypes-base.xsd" 不同并破坏了验证。有人可以帮我解决吗?

4

3 回答 3

2

当具有显式目标命名空间的架构文档(如您的基础设施Root.xsd)使用 xs:include 包含未指定目标命名空间的架构文档(如您的 datatypes-base.xsd)时,第二个架构文档中的声明被解释为尽管它们的包含模式文档与包含模式文档具有相同的命名空间。这种机制有时被称为变色龙包含——包含的模式文档中的声明根据上下文采用这个或那个目标命名空间。

如果不希望命名空间urn:hl7-org:v3捕获复杂类型Customer 和NorwegianCustomer,则infrastructureRoot.xsd 需要使用xs:import,而不是xs:include,并且需要更改默认命名空间以使referencetype="Norwegian_customer"是对{}Norwegian_customer(即,Norwegian_customer作为本地名称且没有命名空间的限定名称)的引用,而不是(现在是)对{urn:hl7-org:v3}Norwegian_customer.

xs:import 构造从不同的命名空间导入组件,而 xs:include 包含来自同一命名空间的组件。Chameleon include 可以看作是使包含的 schema 文档中的组件在一个命名空间中的一种方式;如果它不存在,基础架构模式中的 xs:include 只会引发错误。

于 2013-02-05T23:58:21.723 回答
2

我们一直在 BizTalk 和 .Net 中使用 HL7v3 和 CDA。为了让 CDA 模式正确工作以进行验证并仅发送消息,我必须将 targetnamespace 添加urn:hl7-org:v3到所有“coreschemas”xsd 文件中。之后验证工作和 BizTalk 消息流动。

我对将目标命名空间添加到我并不真正拥有的模式中感到不舒服,但这是一个不错的折衷方案,因为我从未真正改变过模式本身,并且事后工作。

于 2013-02-06T00:19:53.993 回答
0

最初的问题是在将 HL7v3 源导入到我们的自定义数据存储格式和向后导出到 xml 模式期间发现的。第二个模式获取目标命名空间但不是默认命名空间,这会导致验证错误。这是第二个模式导出结果:

<?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>

限制基础属性值的验证失败。根据目标模式设计说明,我们有两种可能的解决方案:

  1. 使用带有“v3”前缀的限定值。
  2. 添加默认命名空间 "xmlns="urn:hl7-org:v3"。
于 2013-02-06T18:09:23.020 回答