2009-05-06 3 views
2

En XML, est-il possible de réutiliser des éléments? En particulier, le problème que j'essaie de résoudre est le suivant. Je veux définir un élément table qui contient un élément tableSchema et un élément dataSource. Je veux le faire d'une manière qu'un table peut se référer à un tableSchema défini ailleurs. Ainsi, je peux avoir plusieurs rapports définissant table s selon le même tableSchema.XML Reuse Question

Pour clarifier, je voudrais être en mesure de faire ce qui suit:

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

et

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

et ont tableSchema s bar et foo définies ailleurs, peut-être dans le même document XML.

Edité pour ajouter: Ici, par tableSchema, je ne veux pas dire un autre schéma Xml. Je veux dire une définition des champs dans un table. Par exemple, je voudrais être en mesure de faire ce qui suit:

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

Ensuite, dans ce qui précède, Report1 définit un rapport qui contient deux table s, un format selon le tableSchemafoo, et un second format selon au tableSchemabar, et Report2 définit un rapport qui contient un table formaté selon le tableSchemafoo et ce schéma est le même que dans Report1.

+0

Je ne suis toujours pas sûr à 100% ce que vous entendez (probablement parce que je manque contexte: Je ne suis pas familier avec le domaine ou exactement le problème que vous faites face). Voulez-vous dire que le texte valorise les définitions de tableSchema (par exemple, bar1, bar1Source, Currency) sont utilisées littéralement? Ou voulez-vous dire qu'ils définissent les éléments qui pourraient être utilisés dans Report1 (c'est-à-dire comme un schéma) Pour le dernier: Les définitions DTD peuvent être intégrées dans le même fichier que le XML (mais elles ont leur propre syntaxe, différente de Éléments XML). – 13ren

+0

Vous avez étiqueté votre question comme "schéma-xml", donc j'ai supposé que vous recherchez un schéma-xml. Mais peut-être que vous pensiez juste que cela pourrait être pertinent? – 13ren

Répondre

2

Vous n'avez pas fourni le contexte de ce qui serait la création/l'analyse de cette XML, mais en supposant que vous avez le contrôle sur ce que vous pouvez alors définir votre propre convention à cet exemple:

<tableSchema ref="foo"> 

Lorsque l'analyseur serait alors Recherchez un élément avec l'ID de "foo" pour récupérer les informations de tableSchema.

+1

... puis recherchez un élément avec l'ID "foo" ... – Javier

+0

Je vais lire le document avec un simple ol '.NET XmlReader. – jason

+0

J'ai effectivement pris votre idée pour résoudre par problème. J'ai ajouté une balise 'externalSchema' avec l'attribut' location' et quand l'analyseur tombe sur l'une de ces balises, il ouvre un autre 'XmlReader' pour analyser le fichier' location' pour lire dans le schéma de la table. Cela m'a donné la réutilisation que je cherchais. Merci. – jason

0

Vous devrez peut-être utiliser une transformation de feuille de style XSL pour faire ce que vous voulez. À la fin, il en résultera un XML complet et résolu.

1

Pourquoi ne pas simplement inclure la définition? Vous définissez dans un schéma XML, puis include où vous voulez l'utiliser dans un autre schéma XML, comme ceci:

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

Il y a un deuxième aspect de votre question: le document XML pour pouvoir spécifier les sorte de tableSchema c'est.

Voici une analogie avec la programmation OO: (1) définir une superclasse, (2) définir foo et bar comme sous-classes de celui-ci. Ensuite, (3) définir le type d'un champ à être de leur superclasse commune; et maintenant (4). un objet d'exécution peut de n'importe quelle sous-classe. Cela a-t-il du sens? Je pense que c'est ce que vous pensez en termes de toute façon.

Pour compléter l'analogie: en XML, une classe est un complexType; une sous-classe est une extension ; un champ est un élément et sa classe est son Type attribut - et la classe d'un objet d'exécution est le xsi: type d'un élément dans un document XML . La chose cruciale est cette dernière partie, xsi: tapez.

(1). Définir la super classe commune - un complexe XMLType:

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

(2). Définir les sous-classes - extensions du complexe ci-dessusType:

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

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

(3). Définir un champ d'être de la superclasse - un élément à la complexType prolongé à partir de:

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

(4). Maintenant, le XML peut spécifier qu'un élément est d'un complexType particulier dans le fichier XML se:

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

Notez que le type est spécial, et est défini dans l'espace de noms donné. En fait, il y a plusieurs problèmes d'espace de noms qui peuvent être frustrants, mais l'élément clé est que c'est possible de faire ce que vous voulez.

Pour un exemple plus complet, veuillez consulter le XML Schema Primer.

+0

Je crois qu'il y a une certaine confusion ici, et c'est de ma faute si je l'ai introduit en utilisant le terme «schéma» en référence à «tableSchema». Je pense que cela aurait été plus clair si j'avais dit "tableDefinition" et précisé qu'il définissait les champs visibles dans un tableau dans un rapport. Je vais modifier le post original pour le rendre plus clair. – jason

0

(Je ne comprends peut-être pas encore la question, mais ...) En supposant que vous voulez utiliser les valeurs de texte dans la tableSchema littéralement, alors c'est vraiment à votre code de traitement. Le XML est juste la représentation des données. Ainsi, vous pouvez faire votre propre format, comme celui-ci par exemple:

<tableSchema ref="foo"/> 

Ensuite, votre outil lit le document en entier, et rappelle les définitions de foo et bar (dans un tableau). Ensuite, il commence à traiter les rapports: quand il utilise Report1, et qu'il voit la référence ci-dessus à foo, il recherche foo dans la table de hachage et l'utilise. Est-ce le genre de chose que vous voulez dire?

Si oui, il y a un peu plus de soutien pour cela avec l'aide d'étiquettes d'identification et IDREF, vous avez ceci:

<tableSchema myidref="foo"/> 

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

Ensuite, (je pense) l'outil d'analyse syntaxique va remplir et rechercher la table toi. Vous devez définir myidref et myid comme de type IDREF et ID dans le schéma/DTD, afin que l'analyseur sache les traiter spécialement. Quelque chose comme (juste montrer myidref):

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