【问题标题】:Multiple Xsd schemas in 1 file1 个文件中的多个 Xsd 架构
【发布时间】:2015-05-29 08:11:28
【问题描述】:

我有多个 Xsd 架构文件(小文件)并想以某种方式将它们组合成一个大文件,我正在考虑一个 xml 文件,其中每个 Xsd 架构内容有 1 个节点,在 C# 代码中选择相应的部分和验证反对它。 问题是我可以在使用 Visual Studio 打开 Xml 文件时看到警告“全局元素 'xxx' 已被声明。”(我绝对不是 Xsd 专家;我确实重复了相同的元素)。

对这种方法的正确性有任何想法吗? 我应该将 CData 用于 Xsd 内容吗?

Xml 文件示例:

XML 1:

<resource xmlns="">
  <identifier>5401902302111</identifier>
  <product>printer</product>
  <requestedby />
</resource>

Xml 2:

<resource xmlns="">
  <identifier>5401902302112</identifier>
  <email>someone@em.com</email>
</resource>

Xsd 1:

<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
            <xs:element name="resource">
              <xs:complexType>
                <xs:sequence>
                  <xs:element type="xs:long" name="identifier"/>
                  <xs:element type="xs:string" name="requestedby"/>
                  <xs:element type="xs:string" name="product"/>
                </xs:sequence>
              </xs:complexType>
            </xs:element>
          </xs:schema>

Xsd 2:

<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
            <xs:element name="resource">
              <xs:complexType>
                <xs:sequence>
                  <xs:element type="xs:long" name="identifier"/>
                  <xs:element type="xs:string" name="email"/>
                </xs:sequence>
              </xs:complexType>
            </xs:element>
          </xs:schema>

我到底想要什么:

*<?xml version="1.0" encoding="utf-8"?>
<resource>
  <resourcedata type="acquisition">
    <details>
      <xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
        <xs:element name="resource">
          <xs:complexType>
            <xs:sequence>
              <xs:element type="xs:long" name="identifier"/>
              <xs:element type="xs:string" name="requestedby"/>
              <xs:element type="xs:string" name="product"/>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:schema>
    </details>
  </resourcedata>
  <resourcedata type="warningletter">
    <details>
      <xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
        <xs:element name="resource">
          <xs:complexType>
            <xs:sequence>
              <xs:element type="xs:long" name="identifier"/>
              <xs:element type="xs:string" name="email"/>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:schema>
    </details>
  </resourcedata>
</data>*

C#代码:

var xsdContent =
                xDoc.Element("resource").Elements("resourcedata")
                    .Where(
                        x =>                            
                            x.Attribute("type").Value == "acquisition")
                    .FirstOrDefault().Element("details").FirstNode.ToString();            


            var doc = new XDocument(xElementContent);

            XmlSchemaSet schemas = new XmlSchemaSet();
            schemas.Add("", XmlReader.Create(new StringReader(xsdContent)));

            Console.WriteLine("Validating doc");
            bool errors = false;
            doc.Validate(schemas, (o, e) =>
            {
                Console.WriteLine("{0}", e.Message);
                Console.WriteLine("{0}", e.Exception);
                errors = true;
            });

            Console.WriteLine("doc {0}", errors ? "did not validate" : "validated");

xElementContent 变量包含 Xml 内容)

谢谢

【问题讨论】:

  • 如果 XSD 文档很小,为什么它们会有多个?为什么没有一个单一的模式文档?你重复一个元素是什么意思?请显示任何相关的 C# 代码和所有模式文件的最小示例,以及要验证的 XML 文档。
  • 您只显示 一个 XSD 文档 - 所有其他都不是架构文件。完全不清楚你在问什么。
  • 我同意马蒂亚斯的观点。然而,这是一种有趣的方法,其动机可能更多是出于误解,而不是要求偏离标准验证实践的特定要求。除非你有具体的、令人信服的理由走这条路,否则我建议你去做more conventionally

标签: xml xsd xsd-validation


【解决方案1】:

与其他人不同,我认为您的问题的唯一问题是它无法说明一个很好的示例,说明为什么要创建您所描述的 XML 文件格式。事实上,我参与了一个有趣的讨论here on SO,C. M. Sperberg-McQueen 甚至为此整理了一个demo,结论是:

因此,它说明了多个符合规范的模式文档可以 嵌入到同一个 XML 文档中。 (因为这似乎是一个 对于一些有关方面的问题,显然也应该注意 此处不涉及 WSDL。)

我觉得有必要链接 CM Sperberg-McQueen 的回答,因为您说 我正在考虑一个 xml 文件而不是 XSD 文件(这将是 kjhughes 的观点) .

为什么我认为你没有展示一个好的场景,是因为下面的单一模式可以很好地满足你的 XML。

<?xml version="1.0" encoding="utf-8"?>
<!--XML Schema generated by QTAssistant/XML Schema Refactoring (XSR) Module (http://www.paschidev.com)-->
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="resource">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="identifier" type="xs:unsignedLong"/>
                <xs:choice>
                    <xs:element minOccurs="0" name="email" type="xs:string"/>
                    <xs:sequence>
                        <xs:element minOccurs="0" name="product" type="xs:string"/>
                        <xs:element minOccurs="0" name="requestedby" type="xs:string"/>                             
                    </xs:sequence>
                </xs:choice>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>

让我们看一些场景(如果您有其他问题,请更新您的问题):

  • 您的根元素可能有不同的名称。在这种情况下,只需创建另一个与该名称匹配的全局元素。
  • 您的根元素可能位于不同的命名空间中。在这种情况下,只需创建另一个 XSD 文件,其 targetNamespace 与您的 XML 命名空间匹配。然后将所有 XSD 添加到 XmlSchemaSet,然后进行验证。
  • 对于相同的元素,您的内容模型可能不同,但在 XSD 1.0 方面是可以协调的(因为您显示的是 .NET 代码,我假设您对 .NET 支持的内容感到困惑)。我在上面创建的架构就是这种情况。
  • 您不能使用 XSD 1.0;它可能会也可能不会与 XSD 1.1 中的功能(例如共同约束、类型替代等)一起使用 - 关键是,XSD 1.1 在这里不适用。然后,您将多个 XSD 放在一个 XML 文件中的建议将很有效。事实上,我认为它是 .NET 世界中 XSD 1.1 的穷人替代方案......

对于后者,我会推荐一种稍微不同的方法。我会使用XInclude 将 XSD 链接到一个文件中 - 如果这是您的处理模型所需要的;有一个 NET 库here。这将允许独立创作 XSD,从而确保每个 XSD 都是有效的,并使用通用编辑器(包括您的 Visual Studio)。

【讨论】:

    【解决方案2】:

    您应该使用基于 xsd:includexsd:import 的标准方法,而不是发明自己的临时方法来组合 XSD。

    另请参阅:What's the difference between xsd:include and xsd:import?

    除非您有非常具体的理由在代码中使用临时方法发送验证,否则您应该在文档级别进行验证,并让解析器为您找到适当的声明。

    【讨论】:

    • 我知道这是“偏离标准验证实践” - 我相应地编辑了问题。我只是想尝试以某种方式消除拥有 > 20 个 Xsd 文件的开销——我可以有大约 20 种类型的 Xml 作为有效请求,并且对于每个我都需要一个单独的 Xsd 文件。我想我可以选择将 Xsd 内容放入 CData 部分。
    • 不过,“以某种方式消除拥有 > 20 个 Xsd 文件的开销”并不能真正证明这种非正统方法的合理性。 (我见过客户使用数百个 XSD 一起顺畅地工作。)此外,不得不求助于 CDATA 应该向您发出信号,表明您正在逆流而上。要么你没有在这里激发你的设计决策,要么你让它变得比它必须的更难。到目前为止,所有迹象都指向后者。不是试图批评,但有时最好的帮助必须建议改变方向。
    • 主要问题是这是否可能\技术上正确(我说我不是 Xsd 专家),从你的回答中我看出基本上不是,所以谢谢你的回复。不幸的是,到目前为止,我所讲述的只是从设计的角度可以提供的所有信息。
    猜你喜欢
    • 2010-11-11
    • 2023-03-29
    • 1970-01-01
    • 2012-12-26
    • 1970-01-01
    • 2018-07-26
    • 1970-01-01
    • 2012-03-06
    • 2018-10-25
    相关资源
    最近更新 更多