用于 xml 架构编译的 Full Framework 和 .NET Core 的不同行为

Posted

技术标签:

【中文标题】用于 xml 架构编译的 Full Framework 和 .NET Core 的不同行为【英文标题】:different behavior for Full Framework and .NET Core for xml schema compilation 【发布时间】:2019-07-12 20:09:50 【问题描述】:

这是我的验证码:

string xsdPath = "base.xsd";
XDocument doc = XDocument.Load(xmlPath);
XmlSchemaSet schemas = new XmlSchemaSet();
schemas.Add("http://some.domain.org", xsdPath);
schemas.Compile();
bool isValid = true;
doc.Validate(schemas, (o, e) => 
    res.AddMessage(MessageSeverities.Error, $"e.Severity:e.Message");
    isValid = false;
);
if ( isValid ) 
    res.AddMessage(
        MessageSeverities.Notice, 
        $"formFile.FileName is valid!");

此代码在桌面应用程序 (.net 4.6) 中使用时运行良好

代码在 .net core asp 2.1 控制器中使用时失败,schemas.Compile(); 引发以下异常:

XmlSchemaException:未声明类型“http://some.domain.org:tAccountingItemTypes”。

似乎相关架构文件没有加载到 asp 核心应用程序中。如何强制加载相关架构?

架构是:

base.xsd

<?xml version="1.0" encoding="utf-8" ?>
<xs:schema 
    targetNamespace="http://some.domain.org" 
    xmlns="http://some.domain.org"
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    elementFormDefault="qualified">

    <xs:include id="enums" schemaLocation="enums.xsd"/>

    <xs:complexType name="tAccountingLines">
      <xs:sequence>
        <xs:element name="AccountingLine" type ="tAccountingLine"></xs:element>
      </xs:sequence>
    </xs:complexType>

    <xs:complexType name="tAccountingLine">
      <xs:sequence>
        <xs:element name="AccountingType" type="tAccountingItemTypes"></xs:element>     
        </xs:element>
      </xs:sequence>    
    </xs:complexType>
</xs:schema>

枚举.xsd

<?xml version="1.0" encoding="utf-8" ?>
<xs:schema 
  targetNamespace="http://some.domain.org" 
  xmlns="http://some.domain.org"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  elementFormDefault="qualified">

  <xs:simpleType name="tAccountingItemTypes">
    <xs:restriction base="xs:string">
      <xs:enumeration value="V1"/>
      <xs:enumeration value="V2"/>
      <xs:enumeration value="V3"/>
    </xs:restriction>
  </xs:simpleType>
</xs:schema>

【问题讨论】:

我的第一个猜测是它解析了错误的相对路径 - 您是否尝试过为 xsdPath 使用绝对路径?例如C:\path\to\base.xsd. @CharlesMager:是的,我来自XmlReader,现在我正在使用xsdPath 的完整路径。 您正在比较 .NET Core 和完整框架的行为,不是 ASP.NET 和桌面。如果您的 ASP.NET Core 应用程序以 Full Framework 为目标,您将看不到任何行为。 (是的,在 Core 和 Full 上运行的 ASP.NET Core 令人困惑) 【参考方案1】:

我刚刚试过这个,它没有加载包含的架构的原因是它用来加载它的解析器是null。这应该可以解决它:

schemas.XmlResolver = new XmlUrlResolver();

我做了一些挖掘,发现这是一个已知的桌面和核心之间的行为变化documented here:

如果正在添加的架构通过外部 URI 导入另一个架构,Core 默认不允许解析该 URI,而 Desktop 允许。要在 Core 上进行解析,需要在添加架构之前调用以下命令:AppContext.SetSwitch("Switch.System.Xml.AllowDefaultResolver", true);

显然,除了开关之外,您还可以显式设置解析器,以便您不使用默认值。

【讨论】:

天哪,我试图找出为什么相同的 XSD 无法验证和 XML 与在 .NET Core 和 .NET Framework 4.7.1 上运行的相同代码现在我知道...谢谢. 经过两天的工作试图解决这个问题,它现在可以工作了。非常感谢。 谢天谢地,我在这里找到了..NET Core XSD 元素未声明

以上是关于用于 xml 架构编译的 Full Framework 和 .NET Core 的不同行为的主要内容,如果未能解决你的问题,请参考以下文章

Standalone.xml 和standalone-full.xml 之间的区别

在 Wildfly 8.2 的standalone-full.xml 中设置系统属性

Sax,Dom,Full解析xml文件

用于 Ivy Bridge 架构的 GNU Fortran 编译器优化标志

xml 用于编译和构建的pom文件的一部分,使用clean compile assembly运行它:single

在ubuntu16编译安装nginx-1.10.2(full)完全自带组件