将嵌套的XML节点与XSLT相结合 [英] combine nested xml nodes with xslt
本文介绍了将嵌套的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屋!
查看全文