XML--XSD--类的循环编程过程
发布日期:2021-07-01 04:36:48 浏览次数:3 分类:技术文章

本文共 9585 字,大约阅读时间需要 31 分钟。

 

 

 

 

Author

Date

hill

2010-11-30

 

 

 

整体模型分析和XML文件解析

 

XML 文件中,可以使用 XDS 文件来检验 XML 文档的正确性。有如下的模型:

 

从上面的模型,可以知道,一直在使用的是“格式”,这些格式就是XML的结构,他生成XSD文件的时候,把数据去掉,剩下XML的结果和一些约束。然后XSD文件可以生成一个C#的类文件,这个类文件里面,根据XSD文件的结构,定义了不同的类,这里类就是XSD文件中描述 XML 文件的结点获取属性等信息。下面通过一个例子来分析这三者之间的循环。

1.  有如下的XML文件:

<?xmlversion="1.0"encoding="utf-8" ?>

<worker>

  <maneger>

    <name>feng1</name>

    <age>25</age>

  </maneger>

  <boss>

    <name>feng2</name>

  </boss>

</worker>

分析这个XML文件,得到:

有一个根元素 worker, 在根元素下面有两个子节点,分别是 manager boss,这样就可以认为,worker 元素有两个属性,是 manager boss

对于结点 manager 还有它自己的子节点,分别是 name, age .可以把 name, age 结点看成 manager 结点的属性。

所以,可以得到这样一个概念,有一个总的对象 worker,这个对象里面有两个属性 manager, boss, 对于 manager ,boss 它们也是一个对象,也有自己的属性,此时,manager对象拥有name, age属性,boss对象拥有 name 属性。

这个时候,就可以抽象出一个类,这个类是worker,该类拥有两个属性 manager, boss 这两个属性还拥有自己的属性,那么就把他们定义成类,所以还有 manager类和 boss 类,此时 manager 类用 name, age 属性,但是nameage属性已经是 string 字符串的类型,不可以再分解,那么就可以在 manager 类中定义 name, age 属性是 string 类型。同理 boss类的 name 定义成 string 类型。

到此我们就可以从 XML 文件中推出自己认为的 .cs 类文件。这个推理可以在后面有XSD文件生成 .cs 类文件的时候来验证。

 

 

文件分析

 

 

<?xmlversion="1.0"encoding="utf-8"?>

<xs:schemaattributeFormDefault="unqualified"elementFormDefault="qualified"xmlns:xs="http://www.w3.org/2001/XMLSchema">

  <xs:elementname="worker">

    <xs:complexType>

      <xs:sequence>

        <xs:elementname="maneger">

          <xs:complexType>

            <xs:sequence>

              <xs:elementname="name"type="xs:string" />

              <xs:elementname="age"type="xs:unsignedByte" />

            </xs:sequence>

          </xs:complexType>

        </xs:element>

        <xs:elementname="boss">

          <xs:complexType>

            <xs:sequence>

              <xs:elementname="name"type="xs:string" />

            </xs:sequence>

          </xs:complexType>

        </xs:element>

      </xs:sequence>

    </xs:complexType>

  </xs:element>

</xs:schema>

 

 

 

类分析

 

 

//------------------------------------------------------------------------------

// <auto-generated>

//     此代码由工具生成。

//     运行时版本:2.0.50727.3053

//

//     对此文件的更改可能会导致不正确的行为,并且如果

//     重新生成代码,这些更改将会丢失。

// </auto-generated>

//------------------------------------------------------------------------------

 

using System.Xml.Serialization;

 

//

// 此源代码由 xsd 自动生成, Version=2.0.50727.3038。

//

 

 

///<remarks/>

[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]

[System.SerializableAttribute()]

[System.Diagnostics.DebuggerStepThroughAttribute()]

[System.ComponentModel.DesignerCategoryAttribute("code")]

[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]

[System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=false)]

public partial class worker {

   

    private object[] itemsField;

   

    ///<remarks/>

    [System.Xml.Serialization.XmlElementAttribute("boss", typeof(workerBoss), Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]

    [System.Xml.Serialization.XmlElementAttribute("maneger", typeof(workerManeger), Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]

    public object[] Items {

        get {

            return this.itemsField;

        }

        set {

            this.itemsField = value;

        }

    }

}

 

///<remarks/>

[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]

[System.SerializableAttribute()]

[System.Diagnostics.DebuggerStepThroughAttribute()]

[System.ComponentModel.DesignerCategoryAttribute("code")]

[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]

public partial class workerBoss {

   

    private string nameField;

   

    ///<remarks/>

    [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]

    public string name {

        get {

            return this.nameField;

        }

        set {

            this.nameField = value;

        }

    }

}

 

///<remarks/>

[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]

[System.SerializableAttribute()]

[System.Diagnostics.DebuggerStepThroughAttribute()]

[System.ComponentModel.DesignerCategoryAttribute("code")]

[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]

public partial class workerManeger {

   

    private string nameField;

   

    private string ageField;

   

    ///<remarks/>

    [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]

    public string name {

        get {

            return this.nameField;

        }

        set {

            this.nameField = value;

        }

    }

   

    ///<remarks/>

    [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]

    public string age {

        get {

            return this.ageField;

        }

        set {

            this.ageField = value;

        }

    }

}

 

文件à生成C#类à生成XML文档àXSD文件检验XML文件

文件

有如下的两个XSD文件,第一个XSD文件引用了第二个XSD文件定义的元素的类型。

以下是第一个XSD文件 xml2_s.xsd 的内容

<?xmlversion="1.0"encoding="utf-8"?>

<xs:schemaid="OrderSchema"

    targetNamespace="http://tempuri.org/OrderSchema"

    elementFormDefault="qualified"

    xmlns="http://tempuri.org/OrderSchema"

    xmlns:mstns="http://tempuri.org/OrderSchema"

    xmlns:xs="http://www.w3.org/2001/XMLSchema"

           xmlns:st ="www.allwins.com"

  <xs:importnamespace="www.allwins.com"schemaLocation="command_xml2.xsd"/>

 

  <xs:complexTypename="people_struct">

    <xs:sequence>

      <xs:elementname="people"type="st:people_name"/>

    </xs:sequence>

  </xs:complexType>

 

  <xs:elementname="root"type="people_struct">

  </xs:element>

 

</xs:schema>

以下是 xml2_s.xsd 引用的 command_xml2.xsd 文件的内容:

<?xmlversion="1.0"encoding="utf-8"?>

<xs:schemaid="command_xml2"

    xmlns:xs="http://www.w3.org/2001/XMLSchema"

           xmlns="www.allwins.com"

           targetNamespace="www.allwins.com"

  <xs:simpleTypename="people_name">

    <xs:restrictionbase="xs:string">

      <xs:minLengthvalue="3"/>

    </xs:restriction>

  </xs:simpleType>

 

</xs:schema>

下面是一个XML文件,可以使用一个上面的xml2_s.xsd 文件来检验,XML文件如下:

<?xmlversion="1.0"encoding="utf-8" ?>

<rootxmlns="http://tempuri.org/OrderSchema"

       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

       >

  <people>allwins</people>

</root>

那么现在拥有了XML文件和XSD文件,就可以使用XSD文件来检验XML文件是否正确,检验的方法是使用“编程来检验,使用XmlReaderSettings 实现”具体的编程检验方法在别的地方讲解。下面是检测之后,得到的结果是:XML文档符合XSD文件的检验

   要是把 allwins 更改为 al ,那么得到的检验结果如下:

http://tempuri.org/OrderSchema:people”元素无效 - 根据数据类型“www.allwins.com:people_name”,值“al”无效 - 实际长度小于 MinLength 值。

分析这个错误的原因就是,在command_xml2.xsd 文件中定义了 people 这个元素的长度是:

<xs:minLengthvalue="3"/>

就是要求最小长度是3

 

所以我们知道了当前这个XSD文件是正确的,可以检验XML文件是否符合它的描述。

那么下去就是要这个XSD文件来生产一个C#类,然后在使用这个C#类序列化成一个XML文件,最后在使用这个XML文件来与该XSD文件检验。看看整个过程是否如上面初始描述的那样。

生产C#类

   可以使用VS中提供的 xsd.exe 来把一个XSD文件生成一个C#类,打开VS的菜单栏---工具---Visual Studio 2008 Command Prompt  然后弹出一个命名行界面。

   进入xml2_s.xsd command_xml2.xsd 文件所在的文件夹,使用 xsd 命令来操作。

输入 xsd xml2_s.xsd /c 会执行错误,错误提示是 类型不正确。错误的原因是我们定义的这个类型是 xml2_s.xsd 文件引用的 command_xml2.xsd 文件,所以必须把该文件同时引用。正确操作是:xsd xml2_s.xsd command_xml2.xsd /c

最后生成一个C#类,名称是 xml2_s_command_xml12.cs 该类的内容如下:

 

///<remarks/>

[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]

[System.SerializableAttribute()]

[System.Diagnostics.DebuggerStepThroughAttribute()]

[System.ComponentModel.DesignerCategoryAttribute("code")]

[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://tempuri.org/OrderSchema")]

[System.Xml.Serialization.XmlRootAttribute("root", Namespace="http://tempuri.org/OrderSchema", IsNullable=false)]

public partial class people_struct {

    private string peopleField;

    ///<remarks/>

    public string people {

        get {

            return this.peopleField;

        }

        set {

            this.peopleField = value;

        }

    }

}

可以看到:

[System.Xml.Serialization.XmlRootAttribute("root", Namespace="http://tempuri.org/OrderSchema", IsNullable=false)]

定义了根元素 root 和他所对应的命名空间,这些是代码编程,都是可以修改的。然后定义一个类,类名是 people_struct,该类中有两个属性是其中一个是 public 类型,对应串行化来说,只串行化 public 类型,而且上面生成的类中定义了一个 private 类型,也是为了使类的封装性更好。

 

类串行化生成XML文档

   串行化的代码如下:

people_struct f = new people_struct();

f.people = "feng";

XmlTextWriter w = new XmlTextWriter("allwins.xml", Encoding.UTF8);

XmlSerializer x = new XmlSerializer(typeof(people_struct));

x.Serialize(w, f);

w.Close();

 

这样就能够把 C# 类定义的对象 f 串行化到一个 XML 文件中,得到的XML文件如下:

  <?xml version="1.0" encoding="utf-8" ?>

<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://tempuri.org/OrderSchema">

  <people>feng</people>

  </root>

然后使用编程验证,使用 xml2_s.xsd 文件验证生成的 allwins.xml 文件,验证的结果是正确的,要是把 feng 该为 fe,那么得到的验证结果如下:

http://tempuri.org/OrderSchema:people”元素无效 - 根据数据类型“www.allwins.com:people_name”,值“fe”无效 - 实际长度小于 MinLength 值。

 

所以整个过程就是实现了:

1.  使用XSD 文件生成C#

2.  使用C#类定义对象,然后赋值,最后串行化成一个XML文档

3.  使用XSD文件检验生成的XML文档

 

 

XML文件àXSD文件检验XML文件

    下面是使用流模型的方法来编写一个XML文档,代码如下:

            const string Filename =allwins.xml";

            XmlTextWriter w = new XmlTextWriter(Filename, Encoding.UTF8);

            w.Formatting = System.Xml.Formatting.Indented; //指定XML文档的排版

            w.WriteStartElement("root", "http://tempuri.org/OrderSchema");

            w.WriteStartAttribute("xsi", null, "http://www.w3.org/2001/XMLSchema-instance ");

            w.WriteEndAttribute();

            w.WriteStartAttribute("xsd", null, "http://www.w3.org/2001/XMLSchema");

            w.WriteEndAttribute();

            w.WriteElementString("people", "feng");

            w.WriteEndElement();

            w.Flush();

            w.Close();

    生成的XML文档如下:

 

 <root xsi="" xsd="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://tempuri.org/OrderSchema">

  <people>feng</people>

  </root>

上面的XML文档生成了一个没有指向元素的前缀,xsi="" xsd="" 对于整个文档来说是没有任何影响的,但是下面为了使用XSD文件来检验它,就应该把他去掉,因为之前编写的XSD文件中没有指定 root 根元素有这样的属性,所以要是xsi="" xsd=""存在,那么XSD文件检测到它的肯定是一个不符合 xml2_s.xsd 文件描述的XML文件

那么去掉xsi="" xsd=""之后得到如下的 XML文档。

<root xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://tempuri.org/OrderSchema">

  <people>feng</people>

  </root>

然后使用 xml2_s.xsd 文件来检验得到该XML文件是符合 xml2_s.xsd 描述的,要是把 people 元素的内容 feng 改为 f,那么检验得到的结果如下。

 

http://tempuri.org/OrderSchema:people”元素无效 - 根据数据类型“www.allwins.com:people_name”,值“f”无效 - 实际长度小于 MinLength 值。

 

所以说明,使用编程方法来生成的XML 文件也可以使用 XSD 来检验。

使用XSD来创建XML和编程创建XML

对于XSD文件是提供了XML文件的框架,当把XSD文件创建成类的时候,有太多的不确定因素,很多东西交给系统去处理可能不够灵活。比如元素前缀的使用之类的细节问题,利用工具生成的C#类会差异。这样使用C#类来串行化得到一个XML,此时的XML文件不一定符合生成它的XSD文件的描述。

因为在C#类这一个环节已经参入很多的人工处理。所以最后生成的XML文件还是要经过XSD文件来检验。

对于使用编程的方法来创建XML文件就比较灵活,怎么样去定义元素,属性和命名空间等问题都是由自己来决定。最后生成XML文件之后,来使用XSD文件来检验。

 

总之,无论使用那一种方法,最后都能够生成XML文件,而且也都要使用XSD文件来检验。

 

 

 

 

 

转载地址:https://mylinux.blog.csdn.net/article/details/8966572 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:select 和 pselect 函数使用的分析
下一篇:推理 arm-linux-gcc/g++ v3.4.1 版本的一个漏洞

发表评论

最新留言

留言是一种美德,欢迎回访!
[***.207.175.100]2024年04月10日 18时30分54秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章