恢复包含在多个文件中的相对链
Restoring relative chain contained in multiple files
本题是上一题的逻辑延续(形式上,只是元素的名字变了,这里,结构上,一切都保持不变)。新条件是现在添加了两个额外的层次结构级别。每个新级别都在单独的 xml 文件中表示。总体目标保持不变:恢复一个文件中从最低元素到最高元素的整个层次结构链。源数据包含在以下文件中:
- 1-base.xml(包含元素地区、城市、街道)
- 2-houses.xml
(包含元素房子)
- 3.rooms.xml(包含元素房间)
我 - base.xml - 解决了过去的部分。在一个文件中恢复层次结构已在较早的 中得到解决。层级模型为parent --> subparent --> child(这里用region --> city --> street表示)。
- child的ID-2="value"等于subparent ID-1="value"
- subparent ID-2="value"等于parent的ID-1="value"
可视化方案 base.xml here
base.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-solution
<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 - houses.xml
全新的可视化方案 here
元素“house”具有互连属性“ID-1”。它将 houses.xml 与 base.xml 联系起来 以下规则适用于此属性:“每个来自 houses.xml 的 ID-1 都与 base.xml ID-1(街道级别)有联系。但并非来自 base.xml 的每个 ID-1 都与来自 houses.xml 的 ID-1 相关(未连接城市和地区级别)。
一些想法:在base.xml示例中恢复运动从较高级别变为较低级别。在这种情况下,我可以假设一个变体以相反的方式进行计算——从低到高。因此提醒一下,直接跟随 ID-1 的行可能不会匹配和恢复所有节点(城市和地区)可能会很有用。
III - rooms.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 -->
houses.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>
rooms.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 文件,但它可以基于例如 rooms.xml 。在特定的解决方案中,它可能会有所不同,完整 parental 链的复制原则很重要。交叉命名的互连属性(HOUSE-ID,ID-1 可能来自不同的路径,具体取决于 soution 的确切表达式。不知何故它们必须保留。
<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 的任何解决方案。第三个版本也很有趣,因为文件大小。如果不切割,它们会很大。所以流媒体版本可以派上用场。
为了轻松地对多个文档使用键,key
函数的 XSLT 2/3 重载将文档或一般子树根节点作为其第三个参数派上用场。
使用它我认为你可以很容易地在 room
元素上构造属性转换为 object
元素:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
version="3.0">
<xsl:param name="base-doc" select="doc('base.xml')"/>
<xsl:param name="houses-doc" select="doc('houses.xml')"/>
<xsl:mode on-no-match="shallow-copy"/>
<xsl:key name="house-ref" match="house" use="@HOUSE-ID"/>
<xsl:key name="doc-ref" match="document" use="@ID-1"/>
<xsl:template match="room">
<object>
<xsl:variable
name="house-ref" select="key('house-ref', @HOUSE-ID, $houses-doc)"/>
<xsl:variable
name="doc-ref"
select="key('doc-ref', $house-ref/@ID-1, $base-doc)"/>
<xsl:variable
name="atts"
select="@*, $house-ref!(@* except @HOUSE-ID), $doc-ref!(@* except (@ID-1, @attr-4))"/>
<xsl:copy-of select="$atts"/>
<xsl:apply-templates select="$doc-ref" mode="att">
<xsl:with-param name="pos" select="3 + 1"/>
</xsl:apply-templates>
</object>
</xsl:template>
<xsl:template match="document" mode="att">
<xsl:param name="pos"/>
<xsl:attribute name="attr-{$pos}">
<xsl:value-of select="@attr-4"/>
</xsl:attribute>
<xsl:apply-templates select="key('doc-ref', @ID-2)" mode="att">
<xsl:with-param name="pos" select="$pos + 1"/>
</xsl:apply-templates>
</xsl:template>
</xsl:stylesheet>
在 https://xsltfiddle.liberty-development.net/bFWRAoL/1(内联其他文档以确保示例的完整性)给出
<rooms>
<object ROOM-ID="value" HOUSE-ID="zzzz" roomnum="123" roomtype="value" ID-1="aaa" housenum="17" buildnum="a" ID-2="cityID" ID-3="value" attr-4="street-1" attr-5="city" attr-6="region"/>
<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"/>
</rooms>
我还没有从辅助文档中了解哪些元素需要copied/transformed。
本题是上一题的逻辑延续
- 1-base.xml(包含元素地区、城市、街道)
- 2-houses.xml (包含元素房子)
- 3.rooms.xml(包含元素房间)
我 - base.xml - 解决了过去的部分。在一个文件中恢复层次结构已在较早的
- child的ID-2="value"等于subparent ID-1="value"
- subparent ID-2="value"等于parent的ID-1="value"
可视化方案 base.xml here
base.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-solution
<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 - houses.xml 全新的可视化方案 here
元素“house”具有互连属性“ID-1”。它将 houses.xml 与 base.xml 联系起来 以下规则适用于此属性:“每个来自 houses.xml 的 ID-1 都与 base.xml ID-1(街道级别)有联系。但并非来自 base.xml 的每个 ID-1 都与来自 houses.xml 的 ID-1 相关(未连接城市和地区级别)。
一些想法:在base.xml示例中恢复运动从较高级别变为较低级别。在这种情况下,我可以假设一个变体以相反的方式进行计算——从低到高。因此提醒一下,直接跟随 ID-1 的行可能不会匹配和恢复所有节点(城市和地区)可能会很有用。
III - rooms.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 -->
houses.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>
rooms.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 文件,但它可以基于例如 rooms.xml 。在特定的解决方案中,它可能会有所不同,完整 parental 链的复制原则很重要。交叉命名的互连属性(HOUSE-ID,ID-1 可能来自不同的路径,具体取决于 soution 的确切表达式。不知何故它们必须保留。
<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 的任何解决方案。第三个版本也很有趣,因为文件大小。如果不切割,它们会很大。所以流媒体版本可以派上用场。
为了轻松地对多个文档使用键,key
函数的 XSLT 2/3 重载将文档或一般子树根节点作为其第三个参数派上用场。
使用它我认为你可以很容易地在 room
元素上构造属性转换为 object
元素:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
version="3.0">
<xsl:param name="base-doc" select="doc('base.xml')"/>
<xsl:param name="houses-doc" select="doc('houses.xml')"/>
<xsl:mode on-no-match="shallow-copy"/>
<xsl:key name="house-ref" match="house" use="@HOUSE-ID"/>
<xsl:key name="doc-ref" match="document" use="@ID-1"/>
<xsl:template match="room">
<object>
<xsl:variable
name="house-ref" select="key('house-ref', @HOUSE-ID, $houses-doc)"/>
<xsl:variable
name="doc-ref"
select="key('doc-ref', $house-ref/@ID-1, $base-doc)"/>
<xsl:variable
name="atts"
select="@*, $house-ref!(@* except @HOUSE-ID), $doc-ref!(@* except (@ID-1, @attr-4))"/>
<xsl:copy-of select="$atts"/>
<xsl:apply-templates select="$doc-ref" mode="att">
<xsl:with-param name="pos" select="3 + 1"/>
</xsl:apply-templates>
</object>
</xsl:template>
<xsl:template match="document" mode="att">
<xsl:param name="pos"/>
<xsl:attribute name="attr-{$pos}">
<xsl:value-of select="@attr-4"/>
</xsl:attribute>
<xsl:apply-templates select="key('doc-ref', @ID-2)" mode="att">
<xsl:with-param name="pos" select="$pos + 1"/>
</xsl:apply-templates>
</xsl:template>
</xsl:stylesheet>
在 https://xsltfiddle.liberty-development.net/bFWRAoL/1(内联其他文档以确保示例的完整性)给出
<rooms>
<object ROOM-ID="value" HOUSE-ID="zzzz" roomnum="123" roomtype="value" ID-1="aaa" housenum="17" buildnum="a" ID-2="cityID" ID-3="value" attr-4="street-1" attr-5="city" attr-6="region"/>
<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"/>
</rooms>
我还没有从辅助文档中了解哪些元素需要copied/transformed。