Этот вопрос является логическим продолжением предыдущего вопроса (формально меняются только имена элементов. Здесь структурно все остается прежним). Новое условие заключается в том, что теперь добавлены два дополнительных уровня иерархии. Каждый новый уровень представлен в отдельном файле xml. Общая цель остается той же: восстановить всю цепочку иерархии от самого низкого элемента до самого высокого в одном файле. Исходные данные содержатся в следующих файлах:
- 1-base. xml (содержит элементы регион, город, улица)
- 2-дома. xml (содержит элемент house )
- 3. комнаты. xml (содержит элемент комнаты)
I - база. xml - решенная часть в прошлом. Восстановление иерархии в одном файле было решено в более раннем вопросе . Модель иерархии является родительской -> дочерний -> дочерний (здесь представлен регион -> город -> улица).
- идентификатор ребенка-2 = "значение" равен идентификатору дочернего элемента- 1 = "значение"
- подзадачник ID-2 = "значение" равно ID родителя-1 = "значение"
схема визуализации для базы. xml здесь
коды решений для базы. xml:
1-источник:
<document ID-1="regionID" ID-2="NULL" ID-3="value" attr-4="region"/> <!-- this is parent's node -->
<document ID-1="cityID" ID-2="regionID" ID-3="value" attr-4="city" /> <!-- this is subparent -->
<document ID-1="aaa" ID-2="cityID" ID-3="value" attr-4="street-1"/> <!-- child-1 -->
<document ID-1="bbb" ID-2="cityID" ID-3="value" attr-4="street-2"/> <!-- child-2 -->
<document ID-1="ccc" ID-2="cityID" ID-3="value" attr-4="street-3"/> <!-- child-3 -->
<document ID-1="ddd" ID-2="cityID" ID-3="value" attr-4="street-4"/> <!-- child-4 -->
2-xslt-решение
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:key name="ref" match="document" use="@ID-1"/>
<xsl:template match="document">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates select="key('ref', @ID-2)" mode="att"/>
</xsl:copy>
</xsl:template>
<xsl:template match="document" mode="att">
<xsl:param name="pos" select="count(@*) + 1"/>
<xsl:attribute name="attr-{$pos}">
<xsl:value-of select="@attr-4"/>
</xsl:attribute>
<xsl:apply-templates select="key('ref', @ID-2)" mode="att">
<xsl:with-param name="pos" select="$pos + 1"/>
</xsl:apply-templates>
</xsl:template>
</xsl:stylesheet>
3 выхода
<document ID-1="regionID" ID-2="NULL" ID-3="value" attr-4="region"/> <!-- this is parent's date -->
<document ID-1="cityID" ID-2="regionID" ID-3="value" attr-4="city" attr-5="region"/> <!-- this is subparent -->
<document ID-1="aaa" ID-2="cityID" ID-3="value" attr-4="street-1" attr-5="city" attr-6="region" /> <!-- child-1 -->
<document ID-1="bbb" ID-2="cityID" ID-3="value" attr-4="street-2" attr-5="city" attr-6="region" /> <!-- child-2 -->
<document ID-1="ccc" ID-2="cityID" ID-3="value" attr-4="street-3" attr-5="city" attr-6="region" /> <!-- child-3 -->
<document ID-1="ddd" ID-2="cityID" ID-3="value" attr-4="street-4" attr-5="city" attr-6="region" /> <!-- child-4 -->
II - дома. xml полная новая схема визуализации здесь
Элемент «Дом» имеет взаимосвязанный атрибут «ID-1». Он соединяет дома. xml с базой. xml Для этого атрибута действует следующее правило: «Каждый ID-1 из домов. xml имеет связь с базой. xml ID-1 (улица lvl). Но не каждый ID-1 из базы. xml связан с ID-1 из домов. xml (не связаны между собой города и области).
некоторые мысли: в базе. xml Пример восстановления движения перешел с более высокого уровня на низкий. В этом случае я могу предположить вариант, который делает вычисления противоположным образом - от низкого к верху. Поэтому, возможно, было бы полезно напомнить, что прямое следование линии ID-1 может не совпадать и восстановить все узлы (город и регион).
III - комнаты. xml - файл самого низкого уровня
, поэтому все исходные коды:
base. xml
<document ID-1="regionID" ID-2="NULL" ID-3="value" attr-4="region"/> <!-- this is parent's node -->
<document ID-1="cityID" ID-2="regionID" ID-3="value" attr-4="city" /> <!-- this is subparent -->
<document ID-1="aaa" ID-2="cityID" ID-3="value" attr-4="street-1"/> <!-- child-1 -->
<document ID-1="bbb" ID-2="cityID" ID-3="value" attr-4="street-2"/> <!-- child-2 -->
<document ID-1="ccc" ID-2="cityID" ID-3="value" attr-4="street-3"/> <!-- child-3 -->
<document ID-1="ddd" ID-2="cityID" ID-3="value" attr-4="street-4"/> <!-- child-4 -->
домов. xml
<houses>
<house ID-1="aaa" HOUSE-ID="zzzz" housenum="17" buildnum="a"/>
<house ID-1="bbb" HOUSE-ID="yyyy" housenum="18" buildnum="NULL"/>
<house ID-1="ccc" HOUSE-ID="xxxx" housenum="19" buildnum="NULL"/>
<house ID-1="ddd" HOUSE-ID="wwww" housenum="20" buildnum="NULL"/>
</houses>
комнат. xml
<rooms>
<room ROOM-ID="value" HOUSE-ID="zzzz" roomnum="123" roomtype="value"/>
<room ROOM-ID="value" HOUSE-ID="yyyy" roomnum="345" roomtype="value"/>
<room ROOM-ID="value" HOUSE-ID="xxxx" roomnum="567" roomtype="value"/>
<room ROOM-ID="value" HOUSE-ID="wwww" roomnum="789" roomtype="value"/>
</rooms>
приблизительный вывод. Здесь предполагается вывод, представленный в виде нового файла. xml, но он может основываться, например, на комнатах. xml. В частном решении это может отличаться, важен принцип воспроизводства полной родительской цепи. Перекрестно названные соединительные атрибуты (HOUSE-ID, ID-1 могут исходить из разных путей, в зависимости от точного выражения выражения. Каким-то образом они просто должны оставаться.
<Restored-Objects>
<object ROOM-ID="value" HOUSE-ID="zzzz" roomnum="123" roomtype="value" <!--room attrributes -->
ID-1="aaa" housenum="17" buildnum="a" <!--house attrributes -->
ID-2="cityID" ID-3="value" attr-4="street-1" attr-5="city" attr-6="region" <!--base attrributes -->
/>
<object ROOM-ID="value" HOUSE-ID="yyyy" roomnum="345" roomtype="value"
ID-1="bbb" housenum="18" buildnum="NULL"
ID-2="cityID" ID-3="value" attr-4="street-2" attr-5="city" attr-6="region"
/>
<object ROOM-ID="value" HOUSE-ID="xxxx" roomnum="567" roomtype="value"
ID-1="ccc" housenum="19" buildnum="NULL"
ID-2="cityID" ID-3="value" attr-4="street-3" attr-5="city" attr-6="region"
/>
<object ROOM-ID="value" HOUSE-ID="wwww" roomnum="789" roomtype="value"
ID-1="ddd" housenum="20" buildnum="NULL"
ID-2="cityID" ID-3="value" attr-4="street-4" attr-5="city" attr-6="region"
/>
<object ID-1="regionID" ID-2="NULL" ID-3="value" attr-4="region"/> <!-- this is parent's date -->
<object ID-1="cityID" ID-2="regionID" ID-3="value" attr-4="city" attr-5="region"/> <!-- this is subparent -->
</Restored-Objects>
Я буду рад любому решению от XSLT 1.0 до 3.0. Третья версия также интересна тем, что размеры файлов. Если их не урезать, они большие. Так что пригодная для стриминга версия может пригодиться.