2

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

具体来说,我要解决的问题如下。我想定义一个table包含一个元素tableSchema和一个元素的元素dataSourcetable我想以一种s 可以引用tableSchema其他地方定义的方式来做到这一点。因此,我可以有多个报告table根据相同的定义 s 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>

并且有tableSchemasbarfoo在别处定义,可能在同一个 XML 文档中。

编辑添加:这里,tableSchema,我不是指另一个 Xml 模式。我的意思是定义 a 中的字段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定义了一个包含两个tables 的报告,一个根据 格式化tableSchema foo,第二个根据 格式化tableSchema bar,并Report2定义一个报表,其中包含一个table根据 格式化tableSchema foo并且架构与 中相同的报告Report1

4

4 回答 4

2

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

<tableSchema ref="foo">

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

于 2009-05-06T17:28:13.747 回答
1

为什么不只包括定义?您在一个 XML Schema 中定义它,然后它包含在另一个 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;子类是它的扩展;一个字段是一个元素,它的类是它的类型属性 - 运行时对象的类是XML 文档元素xsi:type。关键是最后一部分,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>

请注意,类型是特殊的,并且在给定的命名空间中定义。事实上,有几个命名空间问题可能令人沮丧,但关键是它可以为所欲为。

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

于 2009-05-06T19:47:36.847 回答
0

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

于 2009-05-06T17:23:40.250 回答
0

(我可能还不明白这个问题,但是......)假设您想按字面意思使用 tableSchema 中的文本值,那么这真的取决于您的处理代码。XML 只是数据的表示。所以你可以制作自己的格式,就像这样说:

<tableSchema ref="foo"/>

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

如果是这样,使用 ID 和 IDREF 标记会对此提供更多支持,所以你有这个:

<tableSchema myidref="foo"/>

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

然后,(我认为)解析工具将为您填充和查找表格。您需要将 myidref 和 myid 定义为 Schema/DTD 中的 IDREF 和 ID 类型,因此解析器知道要特别对待它们。类似于(仅显示 myidref):

<element name="tableSchema">
  <complexType>
    <xsd:attribute name="myidref" type="xsd:IDREF" use="required"/>
  </complexType>
</element>
于 2009-05-06T21:39:58.200 回答