none
XmlSchemaGroup存在的意义? RRS feed

  • 问题

  • 问题是关于System.Xml.Schema.XmlSchemaGroup这个类,看msdn中说明,感觉跟w3c有些出入,
    可能是我理解错误,请大家帮忙。



    msnd中XmlSchemaGroup类有如下示例代码

     // <xs:complexType name="myComplexType">
    
     XmlSchemaComplexType myComplexType = new XmlSchemaComplexType();
    
     schema.Items.Add(myComplexType);
    
     myComplexType.Name = "myComplexType";
    
    
    
     // <xs:group ref="myGroupOfThings"/>
    
     XmlSchemaGroupRef myGroupOfThingsRef = new XmlSchemaGroupRef();
    
     myComplexType.Particle = myGroupOfThingsRef;
    
     myGroupOfThingsRef.RefName = new XmlQualifiedName("myGroupOfThings"); 
    
    

    对应的xsd代码

    <xs:group name="myGroupOfThings">
    
      <xs:sequence>
    
      <xs:element ref="thing1"/>
    
      <xs:element ref="thing2"/>
    
      <xs:element ref="thing3"/>
    
      </xs:sequence>
    
     </xs:group>
    
    
    
     <xs:complexType name="myComplexType">
    
      <xs:group ref="myGroupOfThings"/>
    
      <xs:attribute ref="myAttribute"/>
    
     </xs:complexType>
    
    
    
    

    Group直接放在了XmlSchemaComplexType的Particle属性中
    查看Particle属性
    Gets or sets the compositor type as one of the XmlSchemaGroupRef, XmlSchemaChoice, XmlSchemaAll, or XmlSchemaSequence classes.


    也就是说
    XmlSchemaGroupRef
    XmlSchemaChoice
    XmlSchemaAll
    XmlSchemaSequence
    在同一层次 

    在w3schools上面看了一个例子(当然也可能是这个网站教程的问题)
    http://www.w3schools.com/schema/schema_complex_indicators.asp

    <xs:group name="persongroup">
    
     <xs:sequence>
    
     <xs:element name="firstname" type="xs:string"/>
    
     <xs:element name="lastname" type="xs:string"/>
    
     <xs:element name="birthday" type="xs:date"/>
    
     </xs:sequence>
    
    </xs:group>
    
    
    
    <xs:element name="person" type="personinfo"/>
    
    
    
    <xs:complexType name="personinfo">
    
     <xs:sequence>
    
     <xs:group ref="persongroup"/>
    
     <xs:element name="country" type="xs:string"/>
    
     </xs:sequence>
    
    </xs:complexType>
    
    
    
    
    感觉Group是在
    XmlSchemaChoice
    XmlSchemaAll
    XmlSchemaSequence
    的下层


    这两者之间怎么看都有些冲突,不知道哪个对?

    如果像microsoft写的那样,感觉XmlSchemaGroup这个类没任何存在意义。
    它里面必须用
    XmlSchemaChoice
    XmlSchemaAll
    XmlSchemaSequence
    中的一种。

    而且XmlSchemaGroupRef只可以放在ComplexType的Particle里面,Sequence也可以,为什么中间要隔一个Group呢?

    或者说用XmlSchema命名空间下的类如何实现如下结构的schema??

    <xs:complexType name="personinfo">
    
     <xs:sequence>
    
     <xs:group ref="persongroup"/>
    
     <xs:element name="country" type="xs:string"/>
    
     </xs:sequence>
    
    </xs:complexType>
    
    
    
    

     

    2010年5月17日 9:53

答案

全部回复

  • 其实我想实现如下结构的schema

    <persion>
      <firstName>aa</firstName>
      <lastName>bb</lastName>
      <child>1</child> 
      <child>2</child> 
      <child>3</child> 
      <house>1</house>
      <house>2</house>
      <house>3</house>
      <house>4</house>
      <car>1</car>
      <car>2</car>
    </persion>
    
    

    其中firstName,lastName必须出现,而且只可以一次,child、house、car随便出现,次数不限。

    所有节点的先后顺序都随意。

    我的想法是:

    <xs:group name="persongroup">
     <xs:choice maxOccurs="unbounded">
      <xs:element name="child" type="xs:string"/>
      <xs:element name="house" type="xs:string"/>
      <xs:element name="car" type="xs:date"/>
     </xs:choice>
    </xs:group>
    
    <xs:element name="person" type="personinfo"/>
    
    <xs:complexType name="personinfo">
     <xs:all>
      <xs:element name="firstName" type="xs:string" minOccure="1" maxOccure="1"/>
      <xs:element name="lastName" type="xs:string" minOccure="1" maxOccure="1"/> 
      <xs:group ref="persongroup" minOccure="0" maxOccure="1"/>
     </xs:all>
    </xs:complexType>

    结果在用c#的group时发现,不可以将Group放于All、Sequence、Choice中。。

    很郁闷,大家有什么好的解决方法吗?

    2010年5月17日 10:16
  • 你好

    XmlSchemaGroup这个类 表示 WWW 联合会 (W3C) 指定的 XML 架构的 group 元素。此类在 schema 级别上定义从复杂类型中引用的组。它将若干元素声明归为一组,以便将它们当作一个组并入复杂类型定义。

    比如说就是你这里的

    <xs:group name="myGroupOfThings">
         <xs:sequence>
          <xs:element ref="thing1"/>
          <xs:element ref="thing2"/>
          <xs:element ref="thing3"/>
         </xs:sequence>
        </xs:group>
    定义的组只能从复杂类型中引用。

    它的作用就是可以将这些元素组合在一起 这样可以在很多复杂元素中都可以引用,而不必在很多复杂类中都单独的定义,同时既然定义在一组一般也有一些某些层面上的共性,因此从某种意义上说 它是属于复杂类型下级元素的。

    而那里设置复杂类型XmlSchemaComplexType的Particle属性,获取组合类型或将其设置为 XmlSchemaGroupRefXmlSchemaChoiceXmlSchemaAll XmlSchemaSequence 类之一。http://msdn.microsoft.com/zh-cn/library/system.xml.schema.xmlschemacomplextype.particle(VS.80).aspx

    而这里很显然是设置粒子为myGroupOfThingsRef即Group组的引用,那么它下面就无法再包含Sequence choice这些了等等其他元素。在这里组引用、Choice、All、Sequence是同一个层面上的。

     


    I see you~http://hi.baidu.com/1987raymondMy Blog~~~
    2010年5月18日 7:56
    版主
  • 你好 我刚才测试了请看下面的代码  确实存在问题:

     //all.Items.Add(groupRef);//如果这样设置 那么则会出现错误 无法将XmlSchemaGroupRef转换为XmlSchemaElement,而且MSDN上也有说明Items可以添加XmlSchemaGroupRef子元素,这特别的奇怪
                personInfo.Particle = groupRef;//只有这样设置才可以 但是无法添加其他子元素咯

    运行结果:

    <?xml version="1.0" encoding="gb2312"?>
    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
      <xs:group name="persongroup">
        <xs:choice>
          <xs:element name="child" type="xs:string" />
          <xs:element name="house" type="xs:string" />
          <xs:element name="car" type="xs:date" />
        </xs:choice>
      </xs:group>
      <xs:complexType name="personinfo">
        <xs:group ref="persongroup" />
      </xs:complexType>
      <xs:element name="person" type="personinfo" />
    </xs:schema>

     

    如果这真是一个BUG 那么真如楼主所说 Group的功能就大大减少了 与W3C上面标准也不符合

     private static void TestXmlSchema()
            {
                string ns = "http://www.w3.org/2001/XMLSchema";
                XmlSchema schema = new XmlSchema();
                XmlSchemaGroup personGroup = new XmlSchemaGroup();
                schema.Items.Add(personGroup);
                personGroup.Name = "persongroup";

                XmlSchemaChoice choice = new XmlSchemaChoice();
                personGroup.Particle = choice;

                XmlSchemaElement child = new XmlSchemaElement();
                child.SchemaTypeName = new XmlQualifiedName("string", ns);
                child.Name = "child";
                choice.Items.Add(child);

                XmlSchemaElement house = new XmlSchemaElement();
                house.SchemaTypeName = new XmlQualifiedName("string", ns);
                house.Name = "house";
                choice.Items.Add(house);

                XmlSchemaElement car = new XmlSchemaElement();
                car.Name = "car";
                car.SchemaTypeName = new XmlQualifiedName("date", ns);
                choice.Items.Add(car);

                XmlSchemaComplexType personInfo = new XmlSchemaComplexType();
                personInfo.Name = "personinfo";
                schema.Items.Add(personInfo);

                XmlSchemaAll all = new XmlSchemaAll();
                personInfo.Particle = all;

                XmlSchemaElement firstName = new XmlSchemaElement();
                firstName.Name = "firstName";
                firstName.SchemaTypeName = new XmlQualifiedName("string", ns);
                firstName.MinOccurs = 1;
                firstName.MaxOccurs = 1;
                all.Items.Add(firstName);

                XmlSchemaElement lastName = new XmlSchemaElement();
                lastName.Name = "lastName";
                lastName.SchemaTypeName = new XmlQualifiedName("string", ns);
                lastName.MinOccurs = 1;
                lastName.MaxOccurs = 1;
                all.Items.Add(lastName);

                //注意这里
                XmlSchemaGroupRef groupRef = new XmlSchemaGroupRef();
                groupRef.RefName = new XmlQualifiedName("persongroup");
                //all.Items.Add(groupRef);//如果这样设置 那么则会出现错误 无法将XmlSchemaGroupRef转换为XmlSchemaElement,而且MSDN上也有说明Items可以添加XmlSchemaGroupRef子元素
                personInfo.Particle = groupRef;//只有这样设置才可以 但是无法添加其他子元素咯

               

                XmlSchemaElement person = new XmlSchemaElement();
                person.Name = "person";
                person.SchemaTypeName = new XmlQualifiedName("personinfo");
                schema.Items.Add(person);

                schema.Compile(ValidationCallbackOne);
               
               
               

                XmlNamespaceManager nsmgr = new XmlNamespaceManager(new NameTable());
                nsmgr.AddNamespace("xs", ns);
                schema.Write(Console.Out, nsmgr);

            }

            public static void ValidationCallbackOne(object sender, ValidationEventArgs args)
            {
                Console.WriteLine(args.Message);
            }


    I see you~http://hi.baidu.com/1987raymondMy Blog~~~
    2010年5月18日 8:44
    版主
  • 刚才没仔细查看 错误是不能转换为XmlSchemaElement 而GroupRef确实继承自Object 但是这里却不能添加到Items中

    http://msdn.microsoft.com/zh-cn/library/system.xml.schema.xmlschemasequence.items(VS.80).aspx

    这里的叙述应该有问题。

    同时同意楼主的看法,.NET中的GroupRef何W3C中的不大一致,GroupREf只能作为复杂元素的Particle 而不能添加到Choice、All、Sequence的Items中


    I see you~http://hi.baidu.com/1987raymondMy Blog~~~
    2010年5月18日 8:52
    版主
  • 多谢【Raymond Tang】的回答,对于Group真的很无奈。

    2010年5月28日 2:50