【问题标题】:System.Xml.XmlSchemaSet compile() fills included schema TargetNamespaceSystem.Xml.XmlSchemaSet compile() 填充包含的架构 TargetNamespace
【发布时间】:2013-02-05 17:36:54
【问题描述】:

我有两个 xml 架构:
1) 基础设施Root.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>

我使用以下 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" 不同并且会破坏验证。有人可以帮我解决吗?

【问题讨论】:

  • 首先删除try {...} catch {}。你可能正在吃(隐藏)Exception
  • 另外,你为什么使用XmlTextReader?为什么不直接使用路径,或者更糟糕的是,使用StreamReadernew XmlTextReader() 自 .NET 2.0 起已被弃用。
  • 那里会出现异常,“schemaSet.Add(null, schemaReader)”调用会抛出。
  • XmlTextReader 来自旧代码示例。

标签: c# xml-serialization xsd xmlschemaset


【解决方案1】:

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

我对将目标命名空间添加到我并不真正拥有的架构中感到不舒服,但这是一个不错的折衷方案,因为我从未真正更改过架构本身,并且之后一切正常。

【讨论】:

    【解决方案2】:

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

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

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

    【讨论】:

    • 感谢您的精彩解释。
    • 我调查了变色龙模式,但仍有一些问题。我们使用Compile 加载模式并将其序列化为我们自己的二进制格式。我仍然不清楚为什么Compile 明确设置包含的 XmlSchema 的 targetnamespace 属性,让我在反序列化期间手动删除它。如果在调用 Compile 方法之后从包含的架构中删除 targetnamespace 属性,一切都会正常工作。此外,我相信源 XSD 文件是有效的,因为我尝试的所有第三方 XSD 验证工具都没有发现任何错误。
    • 在我们的例子中可能不适合使用XmlSchemaSet 或其Compile 方法?那么如何预加载所有的外部模式呢?
    【解决方案3】:

    最初的问题是在将 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"。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-11
      • 1970-01-01
      • 1970-01-01
      • 2021-07-28
      • 2021-04-30
      • 1970-01-01
      相关资源
      最近更新 更多