这个问题是上一个问题的逻辑延续(形式上,只更改元素的名称)。在这里,在结构上,一切保持不变)。新的条件是,现在添加了两个额外的层次结构级别。每个新级别都在一个单独的xml文件中表示。总体目标保持不变:将整个层次结构链从最低的元素恢复到一个文件中的最高层次。源数据包含在以下文件中:
I -- base.xml --解决了过去的问题。在一个文件中还原层次结构是在早期的问题中解析的。层次模型是父->子->子(这里用区域->城市->街道表示)。
面向的base.xml 这里可视化方案
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-解决方案
<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全新可视化方案这里
元素“house”具有一个相互连接的属性“ID-1”。它将houses.xml与base.xml连接起来,以下规则适用于此属性:“来自houses.xml的每个ID-1都与base.xml ID-1 (street )连接。但并非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。在不同的粒子溶液中,完整亲本链的繁殖原理是非常重要的。交叉命名的互连属性(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>我欢迎XSLT1.0到3.0的任何解决方案。第三个版本也很有趣,因为文件大小。如果不切,它们就很大。所以一个可流的版本可以派上用场。
发布于 2020-01-06 19:26:22
为了方便地将键与多个文档一起使用,key函数的XSLT2/3重载(将文档或通常的子树根节点作为其第三个参数)派上用场。
使用它,我认为您可以很容易地在转换为object元素的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>我还不知道哪些元素需要从辅助文档中复制/转换。
https://stackoverflow.com/questions/59604771
复制相似问题