代码之家  ›  专栏  ›  技术社区  ›  magol Nathaniel Roark

用xsd验证XML文件时出错

  •  0
  • magol Nathaniel Roark  · 技术社区  · 14 年前

    我试图用xsd验证一个XML文件,但是我得到了一个“ 找不到元素“xxx”的架构信息 “对于每个元素和属性。

    我的C代码是:

    public ReadeXmlFile(string FilePath)
    {
        var settings = new XmlReaderSettings
        {
           IgnoreComments = true, 
           ValidationType = ValidationType.Schema,
           CheckCharacters=true,
           ValidationFlags= XmlSchemaValidationFlags.ReportValidationWarnings
        };
        settings.ValidationEventHandler += settings_ValidationEventHandler;
        var xsdReader = new XmlTextReader("KeyEmFileSchema.xsd");
        settings.Schemas.Add(null, xsdReader);
    
        using (var reader = XmlTextReader.Create(FilePath, settings))
        {
           while (reader.Read()){}
        }
    }
    
    void settings_ValidationEventHandler(object sender, ValidationEventArgs e)
    {
         Debug.WriteLine(e.Severity + " - " + e.Message);
    }
    

    我的XML文件:

    <?xml version="1.0" encoding="utf-16"?>
    <keyem description="test"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
           xmlns:xsd="http://www.w3.org/2001/XMLSchema"
           xsi:noNamespaceSchemaLocation="http://tempuri.org/KeyEmFileSchema.xsd"
    >
      <layout type="keyboard" height="300" width="300">
        <groupp text="rad 1">
          <key color="Black" macro="{ESC}10{ESC}43{MOUSERESET}" text="Ordi-\nnarie"/>
          <key color="Gray"  macro="{ESC}10{ESC}B0{MOUSERESET}" text="Släck\nskärm"/>
          <key color="Gray"  macro="{ESC}1B{ESC}81{MOUSERESET}" text="Skärm\n1"/>
          <key color="Gray"  macro="{ESC}1B{ESC}81{MOUSERESET}" text="Skärm\n2" icon="dfkhfkjsdhfkjdsf">
            <shift color="Blue"  macro="{ESC}1C{ESC}81{MOUSERESET}" text="Annan Skärm"/>
          </key>
          <key color="Gray"  macro="{ESC}1B{ESC}81{MOUSERESET}" text="Skärm\n3"/>
          <empty/>
          <key color="Gray"  macro="{ESC}1B{ESC}81{MOUSERESET}" text="Skärm\n4"/>
        </groupp>
        <group text="rad 2">
          <key color="Black" macro="{ESC}10{ESC}43{MOUSERESET}" text="Ordi-\nnarie"/>
          <key color="Gray"  macro="{ESC}10{ESC}B0{MOUSERESET}" text="Släck\nskärm"/>
          <group color ="Blue" text="test">
            <key color="Gray"  macro="{ESC}1B{ESC}81{MOUSERESET}" text="Skärm\n1"/>
            <key color="Gray"  macro="{ESC}1B{ESC}81{MOUSERESET}" text="Skärm\n2"/>
            <key color="Gray"  macro="{ESC}1B{ESC}81{MOUSERESET}" text="Skärm\n3"/>
          </group>
          <key color="Gray"  macro="{ESC}1B{ESC}81{MOUSERESET}" text="Skärm\n1"/>
          <key color="Gray"  macro="{ESC}1B{ESC}81{MOUSERESET}" text="Skärm\n2"/>
          <key color="Gray"  macro="{ESC}1B{ESC}81{MOUSERESET}" text="Skärm\n3"/>
          <empty/>
          <key color="Gray"  macro="{ESC}1B{ESC}81{MOUSERESET}" text="Skärm\n4"/>
        </group>
      </layout>
    </keyem>
    

    我的XSD文件

    <?xml version="1.0" encoding="utf-16"?>
    <xs:schema id="FileSchema"
        targetNamespace="http://tempuri.org/KeyEmFileSchema.xsd"
        elementFormDefault="qualified"
        xmlns="http://tempuri.org/KeyEmFileSchema.xsd"
        xmlns:mstns="http://tempuri.org/KeyEmFileSchema.xsd"
        xmlns:xs="http://www.w3.org/2001/XMLSchema"
    >
      <xs:annotation>
        <xs:documentation xml:lang="sv-se">Definition av layout</xs:documentation>
      </xs:annotation>
    
      <!--Definition av attribut-->
      <xs:attribute name="description" type="xs:string"/>
      <xs:attribute name="text"        type="xs:string"/>
      <xs:attribute name="height"      type="xs:positiveInteger"/>
      <xs:attribute name="width"       type="xs:positiveInteger"/>
      <xs:attribute name="type"        type="LayoutTypeSet" default="keyboard"/>
      <xs:attribute name="macro"       type="xs:string"/>
      <xs:attribute name="icon"        type="xs:base64Binary"/>
      <xs:attribute name="color"       type="ColorType"/>
    
      <!--Definition av attributgrupp-->
      <xs:attributeGroup name="ShiftKeyAttributeGroup">
        <xs:attribute ref="color" use="optional"/>
        <xs:attribute ref="macro" use="optional"/>
        <xs:attribute ref="text"  use="required"/>
        <xs:attribute ref="icon"  use="optional"/>
      </xs:attributeGroup>
    
      <!--Definition av root-->
      <xs:element name="keyem">
        <xs:complexType>
          <xs:sequence>
            <xs:element name="layout" type="LayoutType" minOccurs="0" maxOccurs="1"/>
          </xs:sequence>
          <xs:attribute ref="description" use="optional"/>
        </xs:complexType>
      </xs:element>
    
      <!--Definition av komplexa typer-->
      <xs:complexType name="GroupKeyType">
        <xs:choice maxOccurs="unbounded">
          <xs:element name="group" type="GroupType" minOccurs="0" maxOccurs="unbounded"/>
          <xs:element name="key"   type="KeyType"   minOccurs="0" maxOccurs="unbounded"/>
        </xs:choice>
      </xs:complexType>
    
      <xs:complexType name="LayoutType">
        <xs:choice maxOccurs="unbounded">
          <xs:element name="group" type="GroupType" minOccurs="0" maxOccurs="unbounded"/>
          <xs:element name="key"   type="KeyType"   minOccurs="0" maxOccurs="unbounded"/>
        </xs:choice>
        <xs:attribute ref="type"   use="required"/>
        <xs:attribute ref="height" use="optional"/>
        <xs:attribute ref="width"  use="optional"/>
      </xs:complexType>
    
      <xs:complexType name="GroupType">
        <xs:choice maxOccurs="unbounded">
          <xs:element name="group" type="GroupType" minOccurs="0" maxOccurs="unbounded"/>
          <xs:element name="key"   type="KeyType"   minOccurs="0" maxOccurs="unbounded"/>
          <xs:element name="empty" type="EmptyType" minOccurs="0" maxOccurs="unbounded"/>
        </xs:choice>
        <xs:attribute ref="text"  use="required"/>
        <xs:attribute ref="color" use="optional"/>
      </xs:complexType>
    
      <xs:complexType name="EmptyType">
        <xs:sequence>
          <xs:element name="empty"/>
        </xs:sequence>
      </xs:complexType>
    
      <xs:complexType name="ShiftType">
        <xs:attributeGroup ref="ShiftKeyAttributeGroup"/>
      </xs:complexType>
    
      <xs:complexType name="KeyType">
        <xs:sequence>
          <xs:element name="shift" type="ShiftType" minOccurs ="0" maxOccurs="1"/>
        </xs:sequence>
        <xs:attributeGroup ref="ShiftKeyAttributeGroup"/>
      </xs:complexType>
    
    
      <!--Definition av enkla typer-->
      <xs:simpleType      name="ColorType">
        <xs:restriction   base="xs:string">
          <!--Regex för att antingen matcha färg angivet på formen #rrggbb eller som är skriven i klarspråk, t.ex. "Green"-->
          <xs:pattern     value="\#[0-9a-fA-F]{6}|[a-zA-Z]+"/>
        </xs:restriction>
      </xs:simpleType>
    
      <xs:simpleType      name="LayoutTypeSet">
        <xs:restriction   base="xs:string">
          <xs:enumeration value="keyboard"/>
          <xs:enumeration value="list"/>
        </xs:restriction>
      </xs:simpleType>
    </xs:schema>
    
    2 回复  |  直到 10 年前
        1
  •  1
  •   Oleg    14 年前

    如果您在 KeyEmFileSchema.xsd 您可以使用的文件 schemaLocation 而不是 noNamespaceSchemaLocation :

    <keyem description="test"
          xmlns="http://tempuri.org/KeyEmFileSchema.xsd"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
          xmlns:xsd="http://www.w3.org/2001/XMLSchema"
          xsi:schemaLocation="http://tempuri.org/KeyEmFileSchema.xsd KeyEmFileSchema.xsd"
    >
    

    它定义文件名(如果需要,它可以与路径一起使用),其中定义 http://tempuri.org/KeyEmFileSchema.xsd 可以找到并使用。然后你可以用

    XmlReaderSettings settings = new XmlReaderSettings ();
    settings.ValidationType = ValidationType.Schema;
    settings.IgnoreWhitespace = true;
    settings.IgnoreComments = true;
    settings.ValidationFlags = XmlSchemaValidationFlags.ProcessSchemaLocation;
    
    XmlReader reader = XmlReader.Create (xmlFilePath, settings);
    

    如果您需要,可以另外使用 ValidationEventHandler . 如果没有处理程序,您将收到有关验证错误的异常信息。

    更新的 :顺便说一下,包括 xmlns="http://tempuri.org/KeyEmFileSchema.xsd" xsi:schemaLocation="http://tempuri.org/KeyEmFileSchema.xsd KeyEmFileSchema.xsd" 在XML文件的根元素中, 将在Visual Studio文本编辑器中看到 XML文件中的错误:

    1. 未声明属性的用法 description 在里面 keyem 元素。
    2. 中所有属性的用法 layout 也未声明的元素。
    3. 用法 groupp 元素而不是 group .

    更新2 :要求编号3:替换 群组 是清楚的。因为没有人评论我的答案,我想有人会问“XML文件的属性有什么问题?”好的,我得多加评论。

    XSD文件中的问题是,您将属性声明为 不是某些简单类型、属性组或某些元素的属性的一部分 . 你只要申报一些 “独立”属性 然后根据“参考”使用。一般来说是可能的,但这种方式需要使用 有资格的 属性 . 因此,如果您在模式中不做任何更改,XML文件的固定版本将如下所示

    <?xml version="1.0" encoding="utf-16"?>
    <keyem xmlns="http://tempuri.org/KeyEmFileSchema.xsd"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:xsd="http://www.w3.org/2001/XMLSchema"
           xsi:schemaLocation="http://tempuri.org/KeyEmFileSchema.xsd KeyEmFileSchema.xsd"
           a:description="test" xmlns:a="http://tempuri.org/KeyEmFileSchema.xsd"
    >
        <layout a:type="keyboard" a:height="300" a:width="300">
            <group a:text="rad 1">
                <key a:color="Black" a:macro="{ESC}10{ESC}43{MOUSERESET}" a:text="Ordi-\nnarie"/>
                <key a:color="Gray"  a:macro="{ESC}10{ESC}B0{MOUSERESET}" a:text="Släck\nskärm"/>
                <key a:color="Gray"  a:macro="{ESC}1B{ESC}81{MOUSERESET}" a:text="Skärm\n1"/>
                <key a:color="Gray"  a:macro="{ESC}1B{ESC}81{MOUSERESET}" a:text="Skärm\n2" a:icon="dfkhfkjsdhfkjdsf">
                    <shift a:color="Blue"  a:macro="{ESC}1C{ESC}81{MOUSERESET}" a:text="Annan Skärm"/>
                </key>
                <key a:color="Gray"  a:macro="{ESC}1B{ESC}81{MOUSERESET}" a:text="Skärm\n3"/>
                <empty><empty/></empty>
                <key a:color="Gray"  a:macro="{ESC}1B{ESC}81{MOUSERESET}" a:text="Skärm\n4"/>
            </group>
            <group a:text="rad 2">
                <key a:color="Black" a:macro="{ESC}10{ESC}43{MOUSERESET}" a:text="Ordi-\nnarie"/>
                <key a:color="Gray"  a:macro="{ESC}10{ESC}B0{MOUSERESET}" a:text="Släck\nskärm"/>
                <group a:color ="Blue" a:text="test">
                    <key a:color="Gray"  a:macro="{ESC}1B{ESC}81{MOUSERESET}" a:text="Skärm\n1"/>
                    <key a:color="Gray"  a:macro="{ESC}1B{ESC}81{MOUSERESET}" a:text="Skärm\n2"/>
                    <key a:color="Gray"  a:macro="{ESC}1B{ESC}81{MOUSERESET}" a:text="Skärm\n3"/>
                </group>
                <key a:color="Gray"  a:macro="{ESC}1B{ESC}81{MOUSERESET}" a:text="Skärm\n1"/>
                <key a:color="Gray"  a:macro="{ESC}1B{ESC}81{MOUSERESET}" a:text="Skärm\n2"/>
                <key a:color="Gray"  a:macro="{ESC}1B{ESC}81{MOUSERESET}" a:text="Skärm\n3"/>
                <empty><empty/></empty>
                <key a:color="Gray"  a:macro="{ESC}1B{ESC}81{MOUSERESET}" a:text="Skärm\n4"/>
            </group>
    
    </layout>
    </keyem>
    

    一句话 : <empty> 元素在您的模式中定义错误,因此为了遵循该模式,我们必须像 <empty><empty/></empty> .

    可能更改的另一个版本(您可能更喜欢)是 在元素或属性组的定义中放置所有属性 . 在您的案例中使用简单类型似乎是不需要的。因此模式的固定版本可以是:

    <?xml version="1.0" encoding="utf-16"?>
    <xs:schema id="FileSchema"
        targetNamespace="http://tempuri.org/KeyEmFileSchema.xsd"
        elementFormDefault="qualified"
        xmlns="http://tempuri.org/KeyEmFileSchema.xsd"
        xmlns:mstns="http://tempuri.org/KeyEmFileSchema.xsd"
        xmlns:xs="http://www.w3.org/2001/XMLSchema"
    >
      <xs:annotation>
        <xs:documentation xml:lang="sv-se">Definition av layout</xs:documentation>
      </xs:annotation>
    
      <!--Definition av attributgrupp-->
      <xs:attributeGroup name="ShiftKeyAttributeGroup">
        <xs:attribute name="color" type="ColorType"/>
        <xs:attribute name="macro" type="xs:string"/>
        <xs:attribute name="text"  type="xs:string" use="required"/>
        <xs:attribute name="icon"  type="xs:base64Binary"/>
      </xs:attributeGroup>
    
      <!--Definition av root-->
      <xs:element name="keyem">
        <xs:complexType>
          <xs:sequence>
            <xs:element name="layout" type="LayoutType" minOccurs="0" maxOccurs="1"/>
          </xs:sequence>
          <xs:attribute name="description" type="xs:string"/>
        </xs:complexType>
      </xs:element>
    
      <!--Definition av komplexa typer-->
      <xs:complexType name="GroupKeyType">
        <xs:choice maxOccurs="unbounded">
          <xs:element name="group" type="GroupType" minOccurs="0" maxOccurs="unbounded"/>
          <xs:element name="key"   type="KeyType"   minOccurs="0" maxOccurs="unbounded"/>
        </xs:choice>
      </xs:complexType>
    
      <xs:complexType name="LayoutType">
        <xs:choice maxOccurs="unbounded">
          <xs:element name="group" type="GroupType" minOccurs="0" maxOccurs="unbounded"/>
          <xs:element name="key"   type="KeyType"   minOccurs="0" maxOccurs="unbounded"/>
        </xs:choice>
        <xs:attribute name="type"   type="LayoutTypeSet" use="required"/>
        <xs:attribute name="height" type="xs:positiveInteger"/>
        <xs:attribute name="width"  type="xs:positiveInteger"/>
      </xs:complexType>
    
      <xs:complexType name="GroupType">
        <xs:choice maxOccurs="unbounded">
          <xs:element name="group" type="GroupType" minOccurs="0" maxOccurs="unbounded"/>
          <xs:element name="key"   type="KeyType"   minOccurs="0" maxOccurs="unbounded"/>
          <xs:element name="empty" minOccurs="0" maxOccurs="unbounded"/>
        </xs:choice>
        <xs:attribute name="text" type="xs:string" use="required" />
        <xs:attribute name="color" type="ColorType"/>
      </xs:complexType>
    
      <xs:complexType name="ShiftType">
        <xs:attributeGroup ref="ShiftKeyAttributeGroup"/>
      </xs:complexType>
    
      <xs:complexType name="KeyType">
        <xs:sequence>
          <xs:element name="shift" type="ShiftType" minOccurs ="0" maxOccurs="1"/>
        </xs:sequence>
        <xs:attributeGroup ref="ShiftKeyAttributeGroup"/>
      </xs:complexType>
    
      <!--Definition av enkla typer-->
      <xs:simpleType      name="ColorType">
        <xs:restriction   base="xs:string">
          <!--Regex för att antingen matcha färg angivet på formen #rrggbb eller som är skriven i klarspråk, t.ex. "Green"-->
          <xs:pattern     value="\#[0-9a-fA-F]{6}|[a-zA-Z]+"/>
        </xs:restriction>
      </xs:simpleType>
    
      <xs:simpleType      name="LayoutTypeSet">
        <xs:restriction   base="xs:string">
          <xs:enumeration value="keyboard"/>
          <xs:enumeration value="list"/>
        </xs:restriction>
      </xs:simpleType>
    </xs:schema>
    

    如果我们将新模式保存在文件中 KeyEmFileSchema1.xsd 然后 KeyEmFileSchema.xml 文件可以与以前几乎相同:

    <?xml version="1.0" encoding="utf-16"?>
    <keyem xmlns="http://tempuri.org/KeyEmFileSchema.xsd"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:xsd="http://www.w3.org/2001/XMLSchema"
           xsi:schemaLocation="http://tempuri.org/KeyEmFileSchema.xsd KeyEmFileSchema1.xsd"
           description="test"
    >
        <layout type="keyboard" height="300" width="300">
            <group text="rad 1">
                <key color="Black" macro="{ESC}10{ESC}43{MOUSERESET}" text="Ordi-\nnarie"/>
                <key color="Gray"  macro="{ESC}10{ESC}B0{MOUSERESET}" text="Släck\nskärm"/>
                <key color="Gray"  macro="{ESC}1B{ESC}81{MOUSERESET}" text="Skärm\n1"/>
                <key color="Gray"  macro="{ESC}1B{ESC}81{MOUSERESET}" text="Skärm\n2" icon="dfkhfkjsdhfkjdsf">
                    <shift color="Blue"  macro="{ESC}1C{ESC}81{MOUSERESET}" text="Annan Skärm"/>
                </key>
                <key color="Gray"  macro="{ESC}1B{ESC}81{MOUSERESET}" text="Skärm\n3"/>
                <empty/>
                <key color="Gray"  macro="{ESC}1B{ESC}81{MOUSERESET}" text="Skärm\n4"/>
            </group>
            <group text="rad 2">
                <key color="Black" macro="{ESC}10{ESC}43{MOUSERESET}" text="Ordi-\nnarie"/>
                <key color="Gray"  macro="{ESC}10{ESC}B0{MOUSERESET}" text="Släck\nskärm"/>
                <group color ="Blue" text="test">
                    <key color="Gray"  macro="{ESC}1B{ESC}81{MOUSERESET}" text="Skärm\n1"/>
                    <key color="Gray"  macro="{ESC}1B{ESC}81{MOUSERESET}" text="Skärm\n2"/>
                    <key color="Gray"  macro="{ESC}1B{ESC}81{MOUSERESET}" text="Skärm\n3"/>
                </group>
                <key color="Gray"  macro="{ESC}1B{ESC}81{MOUSERESET}" text="Skärm\n1"/>
                <key color="Gray"  macro="{ESC}1B{ESC}81{MOUSERESET}" text="Skärm\n2"/>
                <key color="Gray"  macro="{ESC}1B{ESC}81{MOUSERESET}" text="Skärm\n3"/>
                <empty/>
                <key color="Gray"  macro="{ESC}1B{ESC}81{MOUSERESET}" text="Skärm\n4"/>
            </group>
    
    </layout>
    </keyem>
    
        2
  •  1
  •   Marcello Faga    14 年前

    根据您的模式,您的XML中有一个错误的节点:

    <groupp text="rad 1">
    

    可以在该级别插入group或key元素。

    关于您的特定问题,请尝试使用架构文件中的下一个根节点:

    <xs:schema id="FileSchema"
        elementFormDefault="qualified"
        xmlns:xs="http://www.w3.org/2001/XMLSchema"
    >
    ...
    </xs:schema>