XML重用问题

时间:2009-05-06 17:20:57

标签: xml xsd reusability

在XML中,是否可以重用元素?

具体来说,我试图解决的问题如下。我想定义一个包含元素table和元素tableSchema的元素dataSource。我希望以table s可以引用其他地方定义的tableSchema的方式执行此操作。因此,我可以根据相同的table定制tableSchema个多个报告。

为了澄清,我希望能够做到以下几点:

<report name="Report1">
  <page>
    <table>
      <!--reference to tableSchema named "foo"-->
      <dataSource>fooData</dataSource>
    </table>
  </page>
  <page>
    <table> 
      <!--reference to tableSchema named "bar"-->
      <dataSource>barData</dataSource>
    </table>
  </page>
</report>

<report name="Report2">
  <page>
    <table>
      <!--reference to tableSchema named "foo" (same as above!)-->
      <dataSource>anotherFooData</dataSource>
    </table>
  </page>
</report>

并在其他地方定义了tableSchema s barfoo,可能在同一个XML文档中。

编辑添加:这里,通过tableSchema,我不是指另一个Xml架构。我的意思是定义table中的字段。例如,我希望能够做到以下几点:

<tableSchema name="bar">
    <field>
      <displayName>bar1</displayName>
      <sourceName>bar1Source</sourceName>
      <format>Currency</format>
    </field>
    <field>
      <displayName>bar2</displayName>
      <sourceName>bar2Source</sourceName>
      <format>Text</format>
    </field>
</tableSchema>

<tableSchema name="foo">
    <field>
      <displayName>foo1</displayName>
      <sourceName>foo1Source</sourceName>
      <format>Percent</format>
    </field>
</tableSchema>

然后,在上文中,Report1定义了一个包含两个table的报告,一个根据tableSchema foo格式化,另一个根据tableSchema barReport2定义了一个报告,其中包含一个table,该报告根据tableSchema foo格式化,并且该架构是相同的与Report1中一样。

4 个答案:

答案 0 :(得分:2)

您没有提供关于创建/解析此XML的内容的上下文,但假设您可以对此进行控制,那么您可以为此定义自己的约定,例如:

<tableSchema ref="foo">

然后解析器将查找id为“foo”的元素以检索tableSchema信息。

答案 1 :(得分:1)

为什么不包括定义?您可以在一个XML Schema中定义它,然后include在任何想要在另一个XML Schema中使用它的地方定义它,如下所示:

<include schemaLocation="http://www.example.com/schemas/barDef.xsd"/>
<include schemaLocation="http://www.example.com/schemas/fooDef.xsd"/>

您的问题还有第二个方面:XML文档能够指定它是哪种 tableSchema

这是与OO编程的类比:(1)定义超类,(2)将foo和bar定义为它的子类。然后,(3)将字段的类型定义为它们共同的超类;现在(4)。运行时对象可以是任何子类。那有意义吗?无论如何,我认为这就是你的想法。

完成类比:在XML中,类是 complexType ;子类是它的扩展名;字段是元素,它的类是 type 属性 - 运行时对象的类是 xsi:type XML文档中的>元素。关键是最后一部分, xsi:type

(1)。定义公共超类 - XML complexType:

<complexType name="MySuperType">
  ...
</complexType>

(2)。定义子类 - 上述complexType的扩展名:

<complexType name="Foo">
  <complexContent>
    <extension base="MySuperType">
      ...
    </extension>
  </complexContent>
</complexType>

<complexType name="Bar">
  <complexContent>
    <extension base="MySuperType">
      ...
    </extension>
  </complexContent>
</complexType>

(3)。将字段定义为超类 - 从以下扩展的complexType元素:

<element name="tableSchema" type="mySuperType"/>

(4)。现在,XML可以指定元素是XML本身中特定的complexType

<report xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <page>
    <table>
      <tableSchema xsi:type="foo"/>
      <dataSource>fooData</dataSource>
    </table>
  </page>
  <page>
    <table> 
      <tableSchema xsi:type="bar"/>
      <dataSource>barData</dataSource>
    </table>
  </page>
</report>

请注意, type 是特殊的,并在给定的命名空间中定义。事实上,有几个命名空间问题可能令人沮丧,但关键是 可以做你想做的事。

有关更完整的示例,请参阅XML Schema Primer

答案 2 :(得分:0)

您可能必须使用XSL样式表转换来执行您想要的操作。最后,它将生成一个完整且已解析的XML。

答案 3 :(得分:0)

(我可能还不明白这个问题,但是......)假设你想要逐字地使用tableSchema中的文本值,那么它真的取决于你的处理代码。 XML只是数据的表示。所以你可以编写自己的格式,比如说:

<tableSchema ref="foo"/>

然后你的工具读取整个文档,并记住foo和bar的定义(在表格中)。然后,它开始处理Reports:当它使用Report1时,它看到上面的引用foo,它在哈希表中查找foo并使用它。这是你的意思吗?

如果是这样,使用ID和IDREF标签会有更多的支持,所以你有这个:

<tableSchema myidref="foo"/>

<tableSchema myid="foo">
    <field>
      <displayName>foo1</displayName>
      <sourceName>foo1Source</sourceName>
      <format>Percent</format>
    </field>
</tableSchema>

然后,(我认为)解析工具将为您填充并查找表。您需要在Schema / DTD中定义类型IDREF和ID的myidref和myid,因此解析器知道要特别处理它们。像(只显示myidref)的东西:

<element name="tableSchema">
  <complexType>
    <xsd:attribute name="myidref" type="xsd:IDREF" use="required"/>
  </complexType>
</element>