一个文件中有多个Xsd模式

4
我有多个Xsd模式文件(小文件),想将它们合并成一个大文件,我考虑使用一个XML文件,其中每个Xsd模式内容有一个节点,在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");
变量包含Xml内容 感谢。

如果XSD文档很小,为什么要有多个文档?为什么不只有一个单一的模式文档?当你说重复一个元素时,是什么意思?请展示任何相关的C#代码和所有模式文件的最小样本以及要验证的XML文档。 - Mathias Müller
你只展示了一个XSD文档 - 其他所有文件都不是模式文件。完全不清楚你在问什么。 - Mathias Müller
我同意Mathias的看法。虽然这是一种有趣的方法,但它可能更多地受到误解而不是特定要求的驱动,需要偏离标准验证实践。除非你有具体而强有力的理由选择这条路,否则我建议你采用更传统的做法。more conventionally - kjhughes
2个回答

4
与其他人不同,我认为你的问题唯一的问题在于它没有很好地说明为什么要创建一个如你所描述的XML文件格式的好例子。事实上,我参与了一个有趣的讨论(SO上的),C. M. Sperberg-McQueen甚至组织了一个演示,得出结论:

因此,它说明多个符合规范的模式文档可以嵌入同一个XML文档中。(由于这似乎是一些感兴趣的方面的问题,因此还应该指出WSDL在这里没有涉及。)

我觉得必须链接C. M. Sperberg-McQueen的答案,因为你说“我想到的是一个XML文件”,而不是XSD文件(这将是kjhughes的观点)。
我认为你没有展示一个好的场景,是因为以下单个模式将非常好地满足你的XMLs。
<?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在此处无法使用。然后,在一个XML文件中组合多个XSD的提议将起到很好的作用。实际上,我认为这是.NET世界中XSD 1.1的穷人替代品...

对于后者,我建议采用略微不同的方法。我将使用XInclude将XSD链接在一个文件中-如果这是您的处理模型所需的;有一个.NET库here。这将允许独立编写XSD,从而确保每个XSD都是有效的,并使用常见的编辑器(包括Visual Studio)。


2
与其发明自己的、特定的方法来合并XSD,你应该使用基于xsd:includexsd:import的标准方法。

另请参阅:xsd:include和xsd:import之间有什么区别?

除非你有非常特定的原因要在代码中使用特定的临时方法来调度验证,否则你应该在文档级别进行验证,并让解析器为你定位适当的声明。


我理解这是“偏离标准验证实践”的内容 - 我已相应编辑了该问题。我只是想尝试消除掉拥有>20个Xsd文件的开销 - 我可以将大约20种Xml作为有效请求,并且每种Xml都需要一个单独的Xsd文件。我认为可以采用将Xsd内容放入CData部分的替代方案。 - aly
3
然而,“以某种方式消除掉超过20个XSD文件的开销”并不能真正证明这样一个非正统的方法是有道理的。(我见过客户使用数百个XSD文件,它们可以平稳地一起工作。)此外,不得不求助于CDATA应该向您发出信号,表明您在逆流而上。要么您未能激发出设计决策的动力,要么您正在使事情变得比必要的更加困难。到目前为止,所有迹象都指向后者。我不是要批评,但有时最好的帮助是建议改变方向。 - kjhughes
主要问题是这是否可行\技术上正确(我说我不是Xsd专家),从你们的回答中我看到基本上不行,所以谢谢你们的回复。不幸的是,迄今为止我所提供的都是从设计角度提供的所有信息。 - aly

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接