将嵌套的XML节点与XSLT相结合 [英] combine nested xml nodes with xslt

查看:17
本文介绍了将嵌套的XML节点与XSLT相结合的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试梳理以下两个文件:

ls-lr测试

test:
total 8
-rw-r--r-- 1 xxx002 users 212 2013-11-25 17:36 file1.xml
-rw-r--r-- 1 xxx002 users 212 2013-11-25 17:36 file2.xml

cat test/file1.xml

<?xml version="1.0" encoding="ISO-8859-1"?>
<Config>
   <HostGroup Name="X">
      <Host Name="A"/>
   </HostGroup>
   <HostGroup Name="Y">
      <Host Name="A"/>
      <Host Name="B"/>
   </HostGroup>
</Config>

cat test/file2.xml

<?xml version="1.0" encoding="ISO-8859-1"?>
<Config>
   <HostGroup Name="X">
      <Host Name="B"/>
   </HostGroup>
   <HostGroup Name="Z">
      <Host Name="A"/>
      <Host Name="B"/>
   </HostGroup>
</Config>

转换为以下输出:

<?xml version="1.0" encoding="ISO-8859-1"?>
<HostGroup Name="X">
   <Host Name="A"/>
   <Host Name="B"/>
</HostGroup>
<HostGroup Name="Y">
   <Host Name="A"/>
   <Host Name="B"/>
</HostGroup>
<HostGroup Name="Z">
   <Host Name="A"/>
   <Host Name="B"/>
</HostGroup>

到目前为止,我有以下XSLT:

<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema">

<xsl:output method="xml" indent="yes" encoding="ISO-8859-1"/>

<xsl:variable name="collection">
        <xsl:copy-of select="collection('file:/home/xxx002/xslt/test/?select=*.xml;strip-space=yes;recurse=yes')/*"/>
</xsl:variable>

<xsl:variable name="HostGps" select="$collection/Config/HostGroup"/>

<xsl:template name="foo" match="/*">
        <xsl:for-each-group select="$HostGps" group-by="@Name">
                <xsl:sort select="current-grouping-key()"/>
                <xsl:if test="not(./@Name = preceding-sibling::Property/@Name)">
                        <HostGroup>
                        <xsl:attribute name="Name">
                                <xsl:value-of select="current-grouping-key()"/>
                        </xsl:attribute>
                        <xsl:variable name="Hosts">
                                <xsl:perform-sort select="./Host">
                                        <xsl:sort select="@Name"/>
                                </xsl:perform-sort>
                        </xsl:variable>
                        <xsl:copy-of select="$Hosts"/>
                        </HostGroup>
                </xsl:if>
        </xsl:for-each-group>
</xsl:template>

</xsl:stylesheet>

输出不太正确。它只在HostGroup X的第一个实例中拾取主机A。有人能帮我克服这一点吗?

谢谢, 布莱恩

推荐答案

看起来您只需要更改xsl:perform-sort上的select属性。

此XSLT 2.0...

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    exclude-result-prefixes="xs">

    <xsl:output method="xml" indent="yes" encoding="ISO-8859-1"/>

    <xsl:variable name="collection">
        <xsl:copy-of select="collection('file:///C:/Users/dhaley/Desktop/so_test/?select=*.xml;strip-space=yes;recurse=yes')/*"/>
    </xsl:variable>

    <xsl:variable name="HostGps" select="$collection/Config/HostGroup"/>

    <xsl:template name="foo" match="/*">
        <xsl:for-each-group select="$HostGps" group-by="@Name">
            <xsl:sort select="current-grouping-key()"/>
            <xsl:if test="not(./@Name = preceding-sibling::Property/@Name)">
                <HostGroup Name="{current-grouping-key()}">
                    <xsl:variable name="Hosts">
                        <xsl:perform-sort select="current-group()/*">
                            <xsl:sort select="@Name"/>
                        </xsl:perform-sort>
                    </xsl:variable>
                    <xsl:copy-of select="$Hosts"/>
                </HostGroup>
            </xsl:if>
        </xsl:for-each-group>
    </xsl:template>

</xsl:stylesheet>

生成...

<HostGroup Name="X">
   <Host Name="A"/>
   <Host Name="B"/>
</HostGroup>
<HostGroup Name="Y">
   <Host Name="A"/>
   <Host Name="B"/>
</HostGroup>
<HostGroup Name="Z">
   <Host Name="A"/>
   <Host Name="B"/>
</HostGroup>
注意:我还将xsl:attribute替换为AVT,并添加了exclude-result-prefixes。这些并不是绝对必要的。

这篇关于将嵌套的XML节点与XSLT相结合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆