XML Reutilização Pergunta
-
06-07-2019 - |
Pergunta
Em XML, é possível reutilizar elementos?
Especificamente, o problema que estou tentando resolver é o seguinte. Eu quero definir uma table
elemento que contém um tableSchema
elemento e um elemento dataSource
. Eu quero fazer isso de uma maneira que um table
s pode se referir a um tableSchema
definido em outro lugar. Thusly, eu posso ter vários relatórios definindo table
s acordo com o mesmo tableSchema
.
Para esclarecer, eu gostaria ser capaz de fazer o seguinte:
<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>
e
<report name="Report2">
<page>
<table>
<!--reference to tableSchema named "foo" (same as above!)-->
<dataSource>anotherFooData</dataSource>
</table>
</page>
</report>
e ter tableSchema
s bar
e foo
definido em outro lugar, possivelmente no mesmo documento XML.
Editado para acrescentar: Aqui, por tableSchema, eu não quero outro esquema XML. Quero dizer uma definição os campos em um table
. Por exemplo, eu gostaria de ser capaz de fazer o seguinte:
<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>
Em seguida, no exemplo acima, Report1
define um relatório que contém dois table
s, um formatado de acordo com a tableSchema
foo
, e um segundo formatado de acordo com a tableSchema
bar
, e Report2
define um relatório que contém um table
que é formatado de acordo com a o tableSchema
foo
e que esquema é o mesmo que em Report1
.
Solução
Você não fornecer o contexto para o que seria a criação / analisar esse XML, mas supondo que você tenha controle sobre isso, então você pode definir a sua própria convenção para este exemplo:
<tableSchema ref="foo">
Quando o analisador, então, procurar um elemento com o id de "foo" para recuperar a informação tableSchema.
Outras dicas
Por que não apenas incluem a definição? Você defini-lo em um esquema XML, então incluir -lo sempre que quiser usá-lo em outro esquema XML, assim:
<include schemaLocation="http://www.example.com/schemas/barDef.xsd"/>
<include schemaLocation="http://www.example.com/schemas/fooDef.xsd"/>
Há um segundo aspecto a sua pergunta:. Para o documento XML para ser capaz de especificar que tipo de tableSchema é
Aqui está uma analogia com a programação OO: (1) definir uma superclasse, (2) definir foo e bar como subclasses da mesma. Em seguida, (3) definir o tipo de um campo que vai ser de sua superclasse comum; e agora (4). um tempo de execução do objecto pode de qualquer subclasse. Isso faz sentido? Eu acho que é o que você está pensando em termos de qualquer maneira.
Para completar a analogia: em XML, uma classe é uma complexType ; uma subclasse é uma extensão dela; um campo é uma elemento e sua classe é a sua tipo atributo - e a classe de um objeto de tempo de execução é a xsi: type de um elemento em um documento XML . O mais importante é que última parte, xsi:. Tipo
(1). Definir a classe de super comum - um complexType XML:
<complexType name="MySuperType">
...
</complexType>
(2). Definir as subclasses - extensões do complexType acima:
<complexType name="Foo">
<complexContent>
<extension base="MySuperType">
...
</extension>
</complexContent>
</complexType>
<complexType name="Bar">
<complexContent>
<extension base="MySuperType">
...
</extension>
</complexContent>
</complexType>
(3). Definir um campo para ser da superclasse - um elemento a ser do complexType prorrogado a partir de:
<element name="tableSchema" type="mySuperType"/>
(4). Agora, o XML pode especificar que um elemento é de um complexType especial no próprio XML :
<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>
Note que tipo é especial, e é definido no namespace dado. Na verdade, há várias questões de namespace que pode ser frustrante, mas o importante é que ele é possível fazer o que quiser.
Para um exemplo mais completo, consulte o XML Schema Primer .
Você pode ter que usar uma transformação folha de estilo XSL para fazer o que quiser. No final, ele irá resultar em um XML completo e resolvido.
(I pode não entender a questão ainda, mas ...) Supondo que você quiser usar os valores de texto na tableSchema literalmente, então é realmente até o seu código de processamento. O XML é apenas a representação dos dados. Assim, você poderá fazer a sua própria formato, como este exemplo:
<tableSchema ref="foo"/>
Em seguida, a ferramenta lê todo o documento, e lembra as definições de foo e bar (em uma tabela). Em seguida, ele começa a processar os Relatórios: quando ele vai usar Report1, e ver o árbitro acima para foo, parece-se foo na tabela hash e usa isso. É esse o tipo de coisa que você quer dizer?
Se assim for, há um pouco mais de apoio para este com o uso de ID e marcas IDREF, então você tem o seguinte:
<tableSchema myidref="foo"/>
<tableSchema myid="foo">
<field>
<displayName>foo1</displayName>
<sourceName>foo1Source</sourceName>
<format>Percent</format>
</field>
</tableSchema>
Então, (eu acho) a ferramenta de análise irá preencher e procurar o mesa para você. Você precisa definir myidref e myid como do tipo IDREF e ID no esquema / DTD, de modo que o parser sabe tratá-los especialmente. Algo como (apenas mostrando myidref):
<element name="tableSchema">
<complexType>
<xsd:attribute name="myidref" type="xsd:IDREF" use="required"/>
</complexType>
</element>