微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何从 xpath 列表中创建合并的 xml 节点或如何合并单个不一致的节点

如何解决如何从 xpath 列表中创建合并的 xml 节点或如何合并单个不一致的节点

如何从不一致的 xpath 列表创建折叠的 xml 结构? xslt 3.0 / 2.0 是首选。

输入xml

<root>
    <accepted>
        <x xp="vehicle/car/models/model/part/partnumber"/>
        <x xp="vehicle/car/models/model/part/vendor"/>
        <x xp="vehicle/car/models/model/part/vendor/name"/>
        <x xp="vehicle/car/models/model/part/vendor/email"/>
    </accepted>
    <rejected>
        <x xp="vehicle/car/models/model/part/partnumber"/>
        <x xp="vehicle/car/models/model/part/vendor"/>
        <x xp="vehicle/car/models/model/part/vendor/name"/>
        <x xp="vehicle/car/models/model/part/vendor/email"/>
        <x xp="vehicle/car/models/model/part/vendor/telephone"/>
    </rejected>
    <offices>
        <x xp="country/city/name"/>
        <x xp="country/city/district/name"/>
        <x xp="country/city/district/numberofstores"/>
        <x xp="country/city/district/totalrevenue"/>
    </offices>
</root>

期望的输出

<xml>
    <vehicle>
        <car>
            <models>
                <model>
                    <part>
                        <partnumber/>
                        <vendor>
                            <name/>
                            <email/>
                            <telephone/>
                        </vendor>
                    </part>
                </model>
            </models>
        </car>
    </vehicle>
    <country>
        <city>
            <district>
                <name/>
                <numberofstores/>
                <totalrevenue/>
            </district>
        </city>
    </country>
</xml>

我的尝试: 我使用 distinct-values() 删除了重复的 xpath,然后遍历了这个唯一字符串列表。对于每个唯一的字符串,我应用了 tokenize() 并为字符串的每个分隔部分创建了一个嵌套的 xml 元素。结果是我存储在变量中的 xml 节点。但现在的问题是,我最终为每个唯一的 xpath 生成一个子节点,但我不知道如何合并这些节点。 另一个问题是如何将下面的 xml 结构合并到折叠树中? (记住这个源xml来自一个变量)

<xml>
    <vehicle>
        <car>
            <models>
                <model>
                    <part>
                        <partnumber/>
                    </part>
                </model>
            </models>
        </car>
    </vehicle>
    <vehicle>
        <car>
            <models>
                <model>
                    <part>
                        <vendor>
                            <name/>
                        </vendor>
                    </part>
                </model>
            </models>
        </car>
    </vehicle>
    ...
    <country>
        <city>
            <district>
                <name/>
                <numberofstores/>
                <totalrevenue/>
            </district>
        </city>
    </country>
</xml>

解决方法

您可以使用递归分组函数:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:mf="http://example.com/mf"
    exclude-result-prefixes="#all"
    version="3.0">

  <xsl:function name="mf:group" as="element()*">
      <xsl:param name="paths" as="xs:string*"/>
      <xsl:for-each-group select="$paths" group-by="if (contains(.,'/')) then substring-before(.,'/') else if (. != '') then . else ()">
          <xsl:element name="{current-grouping-key()}">
              <xsl:sequence select="mf:group(current-group() ! substring-after(.,'/'))"/>
          </xsl:element>              
      </xsl:for-each-group>
  </xsl:function>

  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="/">
    <xml>
        <xsl:sequence select="mf:group(//@xp)"/>
    </xml>
  </xsl:template>
  
</xsl:stylesheet>

https://xsltfiddle.liberty-development.net/pNvtBGK

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。