代码之家  ›  专栏  ›  技术社区  ›  svoop

如何创建现有XML模式的“方言”

  •  0
  • svoop  · 技术社区  · 8 年前

    open flightmaps 我们正在使用AIXM 4.5(航空信息交换模型的过时版本),定义如下:

    http://www.aixm.aero/schema/4.5/AIXM-Snapshot.xsd

    非常简单的快照文件如下所示:

    <?xml version="1.0" encoding="UTF-8"?>
    <AIXM-Snapshot xmlns:xsi="http://www.aixm.aero/schema/4.5/AIXM-Snapshot.xsd" version="4.5">
      <Ase>
        <codeClass>C</codeClass>
        (...)
      </Ase>
    </AIXM-Snapshot>
    

    到目前为止,仅限内部使用,我们通过简单地使用ad-hoc添加了一些自定义扩展 xt_ -前缀元素和属性:

    <?xml version="1.0" encoding="UTF-8"?>
    <AIXM-Snapshot xmlns:xsi="http://www.aixm.aero/schema/4.5/AIXM-Snapshot.xsd" version="4.5">
      <Ase xt_hasLayers="false">
        <codeClass>C</codeClass>
        <xt_minScale>250</xt_minScale>
        (...)
      </Ase>
    </AIXM-Snapshot>
    

    当然,这不再针对快照XSD进行验证。

    由于许多原因,我们暂时将使用AIXM 4.5作为基本交换格式。然而,我们希望正确地创建自己的“方言”,以适应我们的扩展,并可能以允许根据XSD验证生成的XML的方式进行后端口。

    我们的目标是:一种OFMX(open flightmaps exchange)格式,它是AIXM 4.5的包装,允许标记,例如:

    <?xml version="1.0" encoding="UTF-8"?>
    <AIXM-Snapshot xmlns:xsi="http://www.aixm.aero/schema/4.5/AIXM-Snapshot.xsd" version="4.5" (...)>
      <OFMX:Authority href="http://whatever.com">
        <Ase OFMX:hasLayers="false">
          <codeClass>C</codeClass>
          <OFMX:minScale>250</OFMX:minScale>
          (...)
        </Ase>
      <OFMX:Authority/>
    </AIXM-Snapshot>
    

    只需剥离所有 OFMX: -前缀元素和属性。

    我应该如何解决这个问题?一个简单的 OFMX.xsd 看起来像XML文档,如何在XML文档中引用它?

    非常感谢您的提示!


    @迈克尔·凯

    XML模式1.1不应该是一个问题,所以您的意思是这样的?

    <?xml version="1.0" encoding="UTF-8"?>
    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://openflightmaps.org" elementFormDefault="qualified" attributeFormDefault="unqualified">
      <xs:defaultOpenContent>
        <xs:any/>
      </xs:defaultOpenContent>
      <xs:element name="Authority">
        <xs:attribute name="href" type="xs:string" use="required"/>
      </xs:element>
      <xs:include schemaLocation="AIXM-Snapshot.xsd"/>
    </xs:schema>
    

    然而,include似乎缺少了一些有用的东西,不是吗?

    如果采用这种方法,是否仍有可能定义 OFMX 名称空间来为所有添加的元素和属性添加前缀?

    1 回复  |  直到 8 年前
        1
  •  2
  •   Michael Kay    8 年前

    扩展模式的最佳方式取决于模式的编写方式,尤其是它的设计是否考虑了可扩展性。此模式不明确允许在第三方命名空间中添加元素(即,该模式似乎不包含通配符元素),但至少所有类型(如AirspaceAssociationType)都是全局的,这意味着您可以(如果选择)通过扩展定义从这些类型派生的新类型。如果沿着这条路线走下去,那么实例文档将不得不在xsi:type属性中命名扩展类型,这非常难看。

    考虑到您对项目的看法以及这个特定模式的编写方式,我认为我的首选方法是编写一个XSLT转换来创建AIXM特性的变体。显式包含扩展,或添加通配符(xs:any元素)使扩展有效的xsd。

    如果您准备使用XML模式1.1(这将限制您对模式处理器的选择),那么您可以考虑定义所有这些类型,使其具有开放内容模型,允许第三方命名空间中的元素出现在标准模式定义的元素之后。只需将xs:defaultOpenContent元素添加到模式中,即可完成此操作—您可以定义一个包含此声明的新模式文档,然后在标准AIXM定义的模式中执行xs:include。

    更新

    我在这里犯了个错误。再次阅读规范,似乎 defaultOpenContent 元素的作用域为架构文档(模块):它只影响 xs:complexType 同一模块中的定义,不在包含的模块中。所以看起来好像是对AIXM特性的更改。毕竟需要xsd。

    如果使用defaultOpenContent,则 xs:any 元素可以指定命名空间,并且可以指定 processContents="strict" ,因此可以确保添加到模型中的图元得到验证。当然,您还需要确保聚合模式包括您自己的元素声明以及AIXM定义的声明。