如何创建我们自己的现有XML模式的“方言”(How to create our own “dialect” of an existing XML schema)

编程入门 行业动态 更新时间:2024-10-26 16:21:51
如何创建我们自己的现有XML模式的“方言”(How to create our own “dialect” of an existing XML schema)

在开放式航图上,我们正在与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_ -prefixed元素和属性添加了一些自定义扩展:

<?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作为基础交换格式。 然而,我们想要正确地创建我们自己的“方言”,以便适应我们的扩展,并且可能以允许所得XML针对XSD进行验证的方式回溯事物。

我们的目标是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名称空间来将所有添加的元素和属性加上前缀?

At open flightmaps we're working with AIXM 4.5 (an outdated version of the Aeronautical Information Exchange Model) as defined by:

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

A very simple snapshot file could look as follows:

<?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>
 

Until now and for internal use only, we've added our few custom extensions by simply using ad-hoc xt_-prefixed elements and attributes:

<?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>
 

Of course, this doesn't validate against the snapshot XSD anymore.

Due to many reasons, we'll stay on AIXM 4.5 as our base exchange format for the time being. However, we'd like to correctly create our own "dialect" of in order to accomodate our extensions and maybe backport things in a way which allows the resulting XML to be validated against a XSD.

Our goal: An OFMX (open flightmaps exchange) format which is a wrapper around AIXM 4.5 and allows markup such as:

<?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>
 

The above could be reduced to a valid AIXM 4.5 document by simply stripping all OFMX:-prefixed elements and attributes.

How should I tackle this? How would a simple OFMX.xsd look like and how would it be referenced in the XML document?

Thanks a lot for your hints!


@michael-kay

XML schema 1.1 should not be a problem, so you mean something like this?

<?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>

However, there appears to be something missing for the include to work, doesn't it?

And given this approach, would it still be possible to define an OFMX namespace to prefix all our added elements and attributes with?

最满意答案

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

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

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

UPDATE

我在这里犯了一个错误。 再次阅读规范,看起来defaultOpenContent元素的作用域是一个模式文档(模块):它只影响同一模块中的xs:complexType定义,而不影响包含的模块。 因此,看起来毕竟需要对AIXM-Features.xsd进行更改。

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

The best way to extend a schema depends on the way the schema is written, and in particular whether it is designed with extensibility in mind. This schema doesn't explicitly permit elements to be added in a third party namespace (that is, the schema appears to contain no wildcard elements), but at least all the types like AirspaceAssociationType are global, which means you can (if you choose) define new types that are derived from these by extension. If you go down this route, then your instance documents will have to name the extended type in an xsi:type attribute, which is pretty ugly.

Given what you say about the project and given the way this particular schema is written, I think my preferred approach would be to write an XSLT transformation that creates a variant of AIXM-Features.xsd that either explicitly includes your extensions, or that adds wildcards (xs:any elements) making your extensions valid.

If you're prepared to use XML Schema 1.1 (which would restrict your choice of schema processors) then you could consider defining all these types to have an open content model which allows elements in a third-party namespace to appear after the standard schema-defined elements. That can be done simply by adding an xs:defaultOpenContent element to the schema - you could define a new schema document that contains this declaration and then does an xs:include on the standard AIXM-defined schema.

UPDATE

I made a mistake here. Reading the spec again, it seems the defaultOpenContent element is scoped to a schema document (module): it only affects xs:complexType definitions within the same module, not in included modules. So it looks as if a change to AIXM-Features.xsd is needed after all.

If you do use defaultOpenContent, the xs:any element can specify a namespace, and can specify processContents="strict", so you can ensure that the elements you add to the model are validated. Of course you'll also need to ensure that the aggregate schema includes your own element declarations as well as the AIXM-defined ones.

更多推荐

本文发布于:2023-07-31 22:04:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1348605.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:自己的   方言   模式   XML   schema

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!