如何使用单个complexType元素在代码中创建xmlSchema?

时间:2014-05-15 13:01:27

标签: c# xml validation serialization xsd

在将XML传递给后端系统之前,我需要在元素标记中包装XML。

原始的,未包装的XML元素将对其XSD文件进行验证。 当然,包裹的不是。

如何在代码中创建XmlSchema并在验证XML之前将其提供给XmlSchemaSet

这是解包的xml:

<ns0:Request xmlns:ns0="example.com/Service.xsd" 
             xmlns:ns1="example.com/Data.xsd" 
             xmlns:ns2="example.com/RequestSchema.xsd">
    <ns0:Info>
        <ns2:Id>12345</ns2:BpId>
        <ns2:Name>FOO</ns2:BpName>
        <ns2:Init>BAR</ns2:Initiator>
    </ns0:Info>
    <ns1:DATA>          
    </ns1:DATA>
</ns0:Request>

这是我要在代码

中添加XmlSchema的包装xml
<group xmlns:ns0="example.com/Service.xsd" 
       xmlns:ns1="example.com/Data.xsd" 
       xmlns:ns2="example.com/RequestSchema.xsd">
    <ns0:Request>
        <ns0:Info>
            <ns2:Id>12345</ns2:BpId>
            <ns2:Name>FOO</ns2:BpName>
            <ns2:Init>BAR</ns2:Initiator>
        </ns0:Info>
        <ns1:DATA>          
        </ns1:DATA>
    </ns0:Request>
<group>

这是我尝试过的,但是没有用:

var groupImport = new XmlSchemaImport { Namespace = "example.com/Service.xsd" };
var groupComplexType = new XmlSchemaComplexType
{
    Particle = new XmlSchemaSequence(),
};
var groupElement = new XmlSchemaElement
{
    Name = "group",
    SchemaType = groupComplexType
};

var xmlSchema = new XmlSchema { TargetNamespace = "example.com/group.xsd" };
xmlSchema.Namespaces.Add("xs", "example.com/2001/XMLSchema");
xmlSchema.Includes.Add(groupImport);
xmlSchema.Items.Add(groupElement);
var xmlSchemaSet = new XmlSchemaSet();
xmlSchemaSet.Add(xmlSchema);
xmlSchemaSet.Add(null, "Service.xsd");
xmlSchemaSet.Add(null, "Data.xsd");
xmlSchemaSet.Add(null, "RequestSchema.xsd");

验证时出现此错误:

  

找不到元素&#39; group&#39;。

的架构信息

1 个答案:

答案 0 :(得分:0)

这可能有很多原因:

  1. 架构位置可能不正确,且未找到声明group元素的文件;
  2. 声明生成错误,
  3. 在错误的命名空间中,
  4. 在错误的环境中,等等。
  5. 假设您的其他文件正确验证,正如您在问题中所说,这是您需要生成的XSD(假设Service.xsd位于同一目录中):

    <xs:schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
                xmlns:xs="http://www.w3.org/2001/XMLSchema" 
                xmlns:ns0="example.com/Service.xsd" 
                targetNamespace="example.com/group.xsd">
      <xs:import schemaLocation="Service.xsd" namespace="example.com/Service.xsd" />
      <xs:element name="group">
        <xs:complexType>
          <xs:sequence>
            <xs:element ref="ns0:Request" />
          </xs:sequence>
        </xs:complexType>
      </xs:element>
    </xs:schema>
    

    您可以在文件中进行一些更改,以帮助您生成有效的架构。

    1)缺少导入schemaLocation 在您的代码中,您将生成以下内容:

    <xs:import namespace="example.com/Service.xsd"/>
    

    命名空间只是一个字符串,而不是一个位置。您应该使用SchemaLocation提供架构的网址。这将用于正确生成<xsd:import>(如果您的应用程序您的应用程序根据本地目录找到您的架构,则此可能不是必需的)。要生成此行:

    <xs:import schemaLocation="Service.xsd" namespace="example.com/Service.xsd" />
    

    你应该使用:

    var groupImport = new XmlSchemaImport { 
        Namespace = "example.com/Service.xsd",
        SchemaLocation = "Service.xsd"
    };
    

    2)空序列:您正在生成一个新的Schema,它导入所有其他模式,创建一个包含序列的新复杂类型,但您不会向序列添加任何内容。这就是你要产生的:

    <xs:element name="group">
        <xs:complexType>
          <xs:sequence/>
        </xs:complexType>
      </xs:element>
    

    结果将是group元素的有效声明,但它不允许您在其中放置任何内容。根据您的示例,group元素应包含Request命名空间的example.com/Service.xsd元素。你需要生成:

    <xs:sequence>
        <xs:element ref="ns0:Request" />
    </xs:sequence>
    

    为此,您需要有权访问sequence对象,并重写您的代码:

    XmlSchemaSequence sequence = new XmlSchemaSequence();
    var groupComplexType = new XmlSchemaComplexType
    {
        Particle = sequence,
    };
    

    然后使用限定名称创建元素引用声明,并将其添加到序列中。

    XmlSchemaElement requestRef = new XmlSchemaElement();
    requestRef.RefName = new XmlQualifiedName("ns0:Request");
    sequence.Items.Add(requestRef);
    

    您还必须将该前缀和名称空间声明添加到架构中,以便它能够验证您的合格类型:

    xmlSchema.Namespaces.Add("ns0", "example.com/Service.xsd");
    

    这可能是您问题中的拼写错误,但xs命名空间应以“http://www.w3.org”而不是“example.com”开头:

    xmlSchema.Namespaces.Add("xs", "http://www.w3.org/2001/XMLSchema");
    

    通过这些更改,您应该能够生成一个验证文件的架构。

    以下是使用以下建议修改的代码:

    var groupImport = new XmlSchemaImport { 
        Namespace = "example.com/Service.xsd",
        SchemaLocation = "Service.xsd"
    };
    
    XmlSchemaSequence sequence = new XmlSchemaSequence();
    var groupComplexType = new XmlSchemaComplexType
    {
        Particle = sequence,
    };
    
    var groupElement = new XmlSchemaElement
    {
        Name = "group",
        SchemaType = groupComplexType
    };
    
    XmlSchemaElement requestRef = new XmlSchemaElement();
    requestRef.RefName = new XmlQualifiedName("ns0:Request");
    sequence.Items.Add(requestRef);
    
    var xmlSchema = new XmlSchema { TargetNamespace = "example.com/group.xsd" };
    xmlSchema.Namespaces.Add("xs", "http://www.w3.org/2001/XMLSchema");
    xmlSchema.Namespaces.Add("ns0", "example.com/Service.xsd");
    xmlSchema.Includes.Add(groupImport);
    xmlSchema.Items.Add(groupElement);
    
    var xmlSchemaSet = new XmlSchemaSet();
    xmlSchemaSet.Add(xmlSchema);
    xmlSchemaSet.Add(null, "Service.xsd");
    xmlSchemaSet.Add(null, "Data.xsd");
    xmlSchemaSet.Add(null, "RequestSchema.xsd");