新书推介:《语义网技术体系》
作者:瞿裕忠,胡伟,程龚
   XML论坛     W3CHINA.ORG讨论区     计算机科学论坛     SOAChina论坛     Blog     开放翻译计划     新浪微博  
 
  • 首页
  • 登录
  • 注册
  • 软件下载
  • 资料下载
  • 核心成员
  • 帮助
  •   Add to Google

    >> Oracle, SQL Server与XML,XML在数据挖掘中的应用, PMML.
    [返回] 中文XML论坛 - 专业的XML技术讨论区XML.ORG.CN讨论区 - 高级XML应用『 XML 与 数据库 』 → [分享]W3C XML 架构设计模式:避免复杂性1 查看新帖用户列表

      发表一个新主题  发表一个新投票  回复主题  (订阅本版) 您是本帖的第 12328 个阅读者浏览上一篇主题  刷新本主题   树形显示贴子 浏览下一篇主题
     * 贴子主题: [分享]W3C XML 架构设计模式:避免复杂性1 举报  打印  推荐  IE收藏夹 
       本主题类别:     
     弄清影 美女呀,离线,快来找我吧!天蝎座1983-10-30
      
      
      等级:大一(高数修炼中)
      文章:9
      积分:106
      门派:W3CHINA.ORG
      注册:2005/9/23

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给弄清影发送一个短消息 把弄清影加入好友 查看弄清影的个人资料 搜索弄清影在『 XML 与 数据库 』的所有贴子 引用回复这个贴子 回复这个贴子 查看弄清影的博客楼主
    发贴心情 [分享]W3C XML 架构设计模式:避免复杂性1

    最近看了一些文章,与大家共同分享一下!   
    已经有一些文档试图从一般使用的角度来定义 W3C XML 架构的有效子集,最有影响力的是 Kohsuke Kawaguchi 提出的 W3C XML Schema Made Simple 和 公认标准委员会 (ASC) X12 提出的 X12 Reference Model for XML Design。但是,这两篇文章都极其保守,它们都建议不要使用 W3C XML 架构语言的强大功能,而对不使用这些功能所付出的代价没有进行充分的论述。

    下面是 Kohsuke 最初提出的一些指导方针,以及一些补充建议:
    • 应该使用元素声明、属性组、模型组和简单类型。
    • 应该尽可能使用 XML 命名空间,了解使用它们的正确方法。
    • 不要试图成为 XML 架构的高手。这可能需要花几个月时间。
    • 应该(Kohsuke 最初的指导方针中建议不要)使用复杂类型和属性声明。
    • 不要使用表示法。
    • 应该(Kohsuke 最初的指导方针中建议不要)使用局部声明。
    • 应该慎重(Kohsuke 最初的指导方针中建议不要)使用替换组。
    • 应该慎重(Kohsuke 最初的指导方针中建议不要)使用没有 targetNamespace 属性的架构(即可变架构)。
    在补充的指导方针中,对建议不要使用复杂类型、属性声明和局部声明提出了一些不同意见,并对使用可变架构和替换组两种指导方针进行了阐述,解释了它们的优缺点。
    最后,除了对 Kohsuke 最初的指导方针进行补充以外,还提出了以下建议:
    • 应该使用 key/keyref/unique 而不是使用 ID/IDREF 进行标识约束。
    • 不要使用默认值或固定值,尤其是对于 xs:QName 的类型。
    • 不要使用类型或组重定义。
    • 应该使用简单类型的限制和扩展。
    • 应该使用复杂类型的扩展。
    • 应该慎重使用复杂类型的限制。
    • 应该慎重使用抽象类型。
    • 应该将 elementFormDefault 设置为 qualified,将 attributeFormDefault 设置为 unqualified。
    • 应该使用通配符以提高可扩展性。
    如果您是初学者,除非待解决的问题必须使用标有“慎重”字眼的指导方针,否则最好避免使用这些指导方针。下面对上述建议的合理性进行解释。
    为何应该使用全局和局部元素声明
    元素声明用于指定元素的结构、类型、表现形式和值约束。元素声明在架构文档中是最重要、最常用的构造块。
    作为 xs:schema 元素的子元素出现的元素声明被认为是“全局元素”。全局元素可以被重复使用,既可以被同一架构的其他部分引用,也可以被其他架构文档引用。全局元素的另一重要特性是:它们可以是替换组的成员。由于 W3C XML 架构建议未提供指定有关被验证文档的根元素的机制,因此可以将任意全局元素用作有效文档的根元素。
    未引用全局元素的复杂类型或模型组定义中出现的元素声明被认为是“局部声明”。与全局元素不同,只要不是在同一级中声明,在一个架构中可以有多个名称相同但类型不同的局部元素。W3C XML Schema Primer 的 3.3 节给出了以下示例:
    只能声明一个名为“title”的全局元素,并且该元素仅限于一种类型(例如 xs:string 或 PersonTitle)。但是,可以声明一个名为“title”的局部元素,其类型为字符串,并且是“book”的子元素。在同一架构(目标命名空间)内,还可以声明另一个也叫做“title”的元素,它具有“Mr Mrs Ms”枚举值。
    当需要从目标架构或从其他架构文档重复利用某些元素时,如果元素及其相关类型可以绑定在一起以便广泛使用,则应该将这些元素声明为全局元素。而对于那些仅在声明类型的上下文中有意义且不需要重复使用的元素来说,声明为局部元素更合适一些。
    默认情况下,全局元素的命名空间名称与架构的目标命名空间名称相同,而局部元素没有命名空间名称。这就意味着在默认情况下,当根据全局元素声明来验证 XML 文档中的元素时,这些元素应该具有与全局元素架构的目标命名空间相同的命名空间名称,而当根据局部元素进行验证时,应该没有命名空间名称。以下示例说明了这一点。
    test.xsd
    <?xml version="1.0" encoding="UTF-8" ?>
    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
    targetNamespace="http://www.example.com"
    xmlns="http://www.example.com">

    <!-- 全局元素声明验证来自 http://www.example.com 命名空间的
             <language> 元素  -->
    <xs:element name="language" type="xs:string" />
    <xs:element name="Root" type="sequenceOfLanguages" />
    <xs:element name="Root2" type="sequenceOfLanguages2" />

    <!-- 带有局部元素声明的复杂类型验证不带命名空间名称的
             <language> 元素 -->
    <xs:complexType name="sequenceOfLanguages" >  
      <xs:sequence>
       <xs:element name="language" type="xs:NMTOKEN" maxOccurs="unbounded" />
      </xs:sequence>
    </xs:complexType>

    <!-- 引用了全局元素声明的复杂类型 -->
      <xs:complexType name="sequenceOfLanguages2" >  
      <xs:sequence>
       <xs:element ref="language" maxOccurs="10" />
      </xs:sequence>
    </xs:complexType>
    </xs:schema>

    test.xml
    <?xml version="1.0"?>
    <ex:Root xmlns:ex="http://www.example.com">
    <language>EN</language>
    </ex:Root>

    test2.xml
    <?xml version="1.0"?>
    <ex:Root2 xmlns:ex="http://www.example.com">
    <ex:language>English</ex:language>
    <ex:language>Klingon</ex:language>
    </ex:Root2>
    为何应该使用全局和局部属性声明
    属性声明用于指定属性的类型、可选性和默认信息。
    作为 xs:schema 元素的子元素出现的属性声明被认为是“全局属性”。全局属性可以被重复使用,既可以被同一架构的其他部分引用,也可以被其他架构文档引用。未引用全局属性的复杂类型定义中出现的属性声明被认为是“局部属性”。
    对于那些需要从目标架构和其他架构文档重复使用的类型,应该使用全局属性声明。而对于那些仅在声明类型的上下文中有意义且不需要重复使用的属性来说,声明为局部属性更合适一些。因为属性通常紧密耦合到其父元素中,所以架构作者一般倾向于使用局部属性声明。但是,在某些场合,适用于多个命名空间中的大量元素的全局属性是非常有用的,例如 xsi:type 和 xsi:schemaLocation。
    注意:默认情况下,全局属性的命名空间名称与架构的目标命名空间名称相同,而局部属性没有命名空间名称。这就意味着在默认情况下,当根据全局属性声明来验证 XML 文档中的属性时,这些属性应该具有与全局属性架构的目标命名空间相同的命名空间名称,而当根据局部属性进行验证时,应该没有命名空间名称。以下示例说明了这一点。
    test.xsd
    <?xml version="1.0" encoding="UTF-8" ?>
    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
    targetNamespace="http://www.example.com"
    xmlns="http://www.example.com">

    <!-- 全局属性声明验证来自 http://www.example.com 命名空间的
             language 属性  -->
    <xs:attribute name="language" type="xs:string" />
    <xs:element name="Root" type="sequenceOfNotes" />
    <xs:element name="Root2" type="sequenceOfNotes2" />

    <!-- 带有局部属性声明的复杂类型验证不带命名空间名称的
             language 属性 -->
    <xs:complexType name="sequenceOfNotes" >  
      <xs:sequence>
       <xs:element name="Note" type="xs:string" />
      </xs:sequence>
      <xs:attribute name="language" type="xs:NMTOKEN"  />
    </xs:complexType>

    <!-- 引用了全局属性声明的复杂类型 -->
      <xs:complexType name="sequenceOfNotes2" >  
      <xs:sequence>
       <xs:element name="Note" type="xs:string" />
      </xs:sequence>
      <xs:attribute ref="language" />
    </xs:complexType>
    </xs:schema>

    test.xml
    <?xml version="1.0"?>
    <ex:Root xmlns:ex="http://www.example.com" language="EN" >
    <Note>此处没有任何内容</Note>
    </ex:Root>

    test2.xml
    <?xml version="1.0"?>
    <ex:Root2 xmlns:ex="http://www.example.com" ex:language="英语
             语言">
    <Note>此处没有任何内容</Note>
    </ex:Root2>
    为何应该了解 XML 命名空间对 W3C XML 架构的影响
    对 XML 命名空间的支持已被紧密融合到 W3C XML 架构建议中。许多场合都需要使用命名空间,例如:
    • 引用全局元素、属性或类型时
    • 使用 XPath 表达式进行标识约束时
    • 确定架构中声明可以验证的元素和属性时
    • 导入并包括其他架构文档时
    基于这个原因,建议架构作者熟悉命名空间的工作方式以及对 W3C XML 架构的特殊影响。MSDN 文章 XML Namespaces and How They Affect XPath and XSLT 详细介绍了 XML 命名空间的细节,文章 Working with Namespaces in XML Schema 解释了命名空间对 W3C XML 架构产生的主要影响。
    为何应该始终将 elementFormDefault 设置为“qualified”
    在前一节中,曾提到默认情况下,全局声明用于验证具有命名空间名称的元素或属性,而局部声明用于验证不具有命名空间名称的元素或属性。用来描述具有命名空间名称的元素或属性的术语是“命名空间限定”。根据局部声明是否验证命名空间限定的元素或属性,默认方式可能会被替代。xs:schema 元素具有 elementFormDefault 和 attributeFormDefault 属性,分别用来指定架构中的局部声明是否应该验证命名空间限定的元素或属性。这两个属性的有效值是 qualified 和 unqualified,默认值都是 unqualified。
    同样,局部元素和属性声明的 form 属性可用于替代 xs:schema 元素上指定的 elementFormDefault 和 attributeFormDefault 属性值。这样就可以更精确地控制是根据全局声明还是根据局部声明来验证实例文档中的元素和属性。
    以下示例取自 Kohsuke 文章中的“Why You Should Avoid Local Declarations”一节,它深入分析了这些属性对验证结果的巨大影响。
    架构:
    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
          targetNamespace="http://example.com">
      <xs:element name="person">
        <xs:complexType>
          <xs:sequence>
            <xs:element name="familyName" type="xs:string" />
            <xs:element name="firstName" type="xs:string" />
          <xs:sequence>
        <xs:complexType>
      <xs:element>
    <xs:schema>
    验证以下文档:
    <foo:person xmlns:foo="http://example.com">
      <familyName> KAWAGUCHI <familyName>
      <firstName> Kohsuke <firstName>
    <foo:person>
    ...架构作者通常并不希望这样做,而是在无意中引入。将架构更改为:
    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
          targetNamespace="http://example.com"
         elementFormDefault="qualified">
      <xs:element name="person">
        <xs:complexType>
          <xs:sequence>
            <xs:element name="familyName" type="xs:string" />
            <xs:element name="firstName" type="xs:string" />
          <xs:sequence>
        <xs:complexType>
      <xs:element>
    <xs:schema>
    ...允许它验证以下文档:
    <person xmlns="http://example.com">
      <familyName> KAWAGUCHI <familyName>
      <firstName> Kohsuke <firstName>
    <person>
    —或—
    <foo:person xmlns:foo="http://example.com">
      <foo:familyName> KAWAGUCHI <foo:familyName>
      <foo:firstName> Kohsuke <foo:firstName>
    <foo:person>
    让 attributeFormDefault 属性取默认值 unqualified 是合适的,因为大多数架构作者不希望通过添加前缀来明确地对所有属性进行命名空间限定。
    为何应该使用属性组
    属性组定义是一种创建由属性声明和属性通配符组成的命名集合的方法。属性组有助于架构的模块化,允许您在一处声明常用的属性集合,然后从一个或多个架构中引用。
    注意:Koshuke 的文章中提到属性组可以取代全局属性,这可能会给读者造成两者互相排斥的错误印象。全局声明的属性是独立的,可以重复使用。而属性组是模块化的属性集合,属性组中的属性声明可以是局部声明,也可以是对全局声明的引用。因此,Koshuke 的文章中将属性组描述为可以取代全局属性声明并不是十分准确。
    为何应该使用模型组
    模型组定义是一种使用所有、选项或顺序复合方式来创建命名元素组的机制。模型组适用于那些希望避免复杂类型(特别是类型派生)而需要重复使用某些元素的场合。但是,模型组不能取代复杂类型,因为它们不能包含属性声明,也不能指定元素声明的类型。此外,与复杂类型的派生相比,模型组的派生功能有很多限制。


       收藏   分享  
    顶(0)
      




    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2005/9/23 17:27:00
     
     GoogleAdSense天蝎座1983-10-30
      
      
      等级:大一新生
      文章:1
      积分:50
      门派:无门无派
      院校:未填写
      注册:2007-01-01
    给Google AdSense发送一个短消息 把Google AdSense加入好友 查看Google AdSense的个人资料 搜索Google AdSense在『 XML 与 数据库 』的所有贴子 访问Google AdSense的主页 引用回复这个贴子 回复这个贴子 查看Google AdSense的博客广告
    2024/5/2 17:56:22

    本主题贴数1,分页: [1]

    管理选项修改tag | 锁定 | 解锁 | 提升 | 删除 | 移动 | 固顶 | 总固顶 | 奖励 | 惩罚 | 发布公告
    W3C Contributing Supporter! W 3 C h i n a ( since 2003 ) 旗 下 站 点
    苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》
    8,019.531ms