Вопрос о повторном использовании XML
-
06-07-2019 - |
Вопрос
Можно ли в XML повторно использовать элементы?
В частности, проблема, которую я пытаюсь решить, заключается в следующем.Я хочу определить элемент table
который содержит элемент tableSchema
и элемент dataSource
.Я хочу сделать это таким образом, чтобы table
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>
и имеют tableSchema
с 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
s, один отформатирован в соответствии с tableSchema
foo
, а второй отформатирован в соответствии с tableSchema
bar
, и Report2
определяет отчет, который содержит один table
который отформатирован в соответствии с tableSchema
foo
и эта схема такая же, как и в Report1
.
Решение
Вы не предоставили контекст относительно того, что будет создавать/анализировать этот XML, но если предположить, что у вас есть контроль над этим, вы можете определить для этого свое собственное соглашение, например:
<tableSchema ref="foo">
Затем анализатор будет искать элемент с идентификатором «foo», чтобы получить информацию tableSchema.
Другие советы
Почему бы просто не включить определение?Вы определяете его в одной XML-схеме, затем включать его везде, где вы хотите использовать его в другой схеме XML, например:
<include schemaLocation="http://www.example.com/schemas/barDef.xsd"/>
<include schemaLocation="http://www.example.com/schemas/fooDef.xsd"/>
У вашего вопроса есть второй аспект:чтобы XML-документ мог указать, какой тип таблицаСхема это.
Вот аналогия с объектно-ориентированным программированием:(1) определить суперкласс, (2) определить foo и bar как его подклассы.Затем (3) определите тип поля, принадлежащий их общему суперклассу;и сейчас (4).объект времени выполнения может принадлежать к любому подклассу.Имеет ли это смысл?Я думаю, что это то, о чем вы думаете в любом случае.
Чтобы завершить аналогию:в XML класс — это сложный тип;подкласс – это расширение об этом;поле – это элемент и это класс, это его тип атрибут - и класс объекта времени выполнения является xsi:тип из элемент в XML-документ.Важным является то, что последняя часть, xsi:тип.
(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:
<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-схеме.
Возможно, вам придется использовать преобразование таблицы стилей XSL, чтобы сделать то, что вы хотите.В конечном итоге это приведет к полному и разрешенному XML.
(Возможно, я еще не понял вопрос, но...) Если вы хотите использовать текстовые значения в 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 как типы IDREF и ID в схеме/DTD, чтобы синтаксический анализатор знал, что с ними нужно обращаться особым образом.Что-то вроде (просто показывает myidref):
<element name="tableSchema">
<complexType>
<xsd:attribute name="myidref" type="xsd:IDREF" use="required"/>
</complexType>
</element>