在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 bar
和foo
,可能在同一个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
bar
和Report2
定义了一个报告,其中包含一个table
,该报告根据tableSchema
foo
格式化,并且该架构是相同的与Report1
中一样。
答案 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>