如何创建我们自己的现有XML模式的“方言”

时间:2018-01-30 16:03:24

标签: xml xsd

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(开放式航班地图交换)格式,它是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: - 前缀元素和属性,可以将上述内容简化为有效的AIXM 4.5文档。

我该如何解决这个问题?如何简单OFMX.xsd看起来如何以及如何在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>

然而,包含工作似乎缺少某些东西,不是吗?

根据这种方法,是否仍然可以定义一个OFMX命名空间,以便为我们添加的所有元素和属性添加前缀?

1 个答案:

答案 0 :(得分:1)

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

鉴于你对项目的看法以及这个特定模式的编写方式,我认为我的首选方法是编写一个XSLT转换,创建一个AIXM-Features.xsd的变体,它明确地包含你的扩展,或者添加通配符(xs:任何元素)使您的扩展有效。

如果您准备使用XML Schema 1.1(这将限制您选择的架构处理器),那么您可以考虑将所有这些类型定义为具有允许第三方命名空间中的元素出现的开放内容模型在标准模式定义的元素之后。这可以通过向模式添加xs:defaultOpenContent元素来完成 - 您可以定义包含此声明的新模式文档,然后在标准AIXM定义的模式上执行xs:include。

<强>更新

我在这里搞错了。再次阅读规范,似乎defaultOpenContent元素的范围限定为模式文档(模块):它只影响同一模块中的xs:complexType定义,而不影响包含的模块。因此,看起来好像需要对AIXM-Features.xsd进行更改。

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