我有一个xml文件,其中包含目标主机节点,其属性为:name,host和port。
odnodes.xml:
<odnodes>
<node>
<name>malden_APP_OBC_DEV-1</name>
<host>localhost</host>
<port>20014</port>
<comments></comments>
</node>
<node>
<name>malden_APP_OBC_IT-2</name>
<host>localhost</host>
<port>20014</port>
<comments></comments>
</node>
<node>
<name>finish_IIS_OBC_UAT-1</name>
<host>localhost</host>
<port>20014</port>
<comments></comments>
</node>
<node>
<name>finish_IIS_OBC_PROD-2</name>
<host>localhost</host>
<port>20014</port>
<comments></comments>
</node>
</odnodes>
使用Perl我正在动态创建另一个文件,该文件创建具有以下属性的节点:名称和节点,其中节点填充有相似的节点。
用于创建组名的Perl:
my @names = split(/([_-])/, $groupnames);
my @names = @names[0];
print FILE "@names\n";
Perl用于填充节点属性:
foreach my $group (@groups) {
my @nodes;
foreach my $node (@nodenames) {
chomp($group);
chomp($node);
if ($node =~ m/$group/) {
push (@nodes, "$node,");
}
}
chop @nodes[-1];
my $groupxml = "\t<nodeGroup name=\"$group\" nodes=\"@nodes\"\/>\n";
print ODSERVERFILE $groupxml;
}
示例组节点:
<odConfiguration>
<nodeSet>
<nodeGroup name="malden" nodes="malden_APP_OBC_DEV-1,malden_APP_OBC_IT-2" />
<nodeGroup name="finish" nodes="finish_IIS_OBC_UAT-1,finish_IIS_OBC_PROD-2" />
</nodeSet>
</odConfiguration>
问题:我怎样才能使用XSL实现这一目标?或者,我可以调用我的perl脚本运行并将结果传递给我吗?
答案 0 :(得分:2)
可以使用这个XSLT 2.0样式表来完成,我注意到它比你的Perl代码短:
<odConfiguration xsl:version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<nodeSet>
<xsl:for-each-group select="//node/@name" group-by="substring-before(., '_')">
<nodeGroup name="{current-grouping-key()}"
nodes="{string-join(current-group(), ',')}" />
</xsl:for-each-group>
</nodeSet>
</odConfiguration>
答案 1 :(得分:0)
使用Muenchian方法分组
<强> XSLT 强>:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:key name="k" match="node" use="substring-before(@name, '_')"/>
<xsl:template match="/*">
<xsl:copy>
<xsl:apply-templates select="node[generate-id() = generate-id(key('k', substring-before(@name, '_')))]">
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<xsl:template match="node">
<nodeGroup name="{substring-before(@name, '_')}">
<xsl:attribute name="nodes">
<xsl:for-each select="key('k', substring-before(@name, '_'))">
<xsl:value-of select="substring-after(@name, '_')"/>
<xsl:if test="position() != last()">
<xsl:text>,</xsl:text>
</xsl:if>
</xsl:for-each>
</xsl:attribute>
</nodeGroup>
</xsl:template>
</xsl:stylesheet>
<强>输入强>:
<root>
<node name="malden_APP_OBC_DEV-1" host="localhost" port="20014" />
<node name="malden_APP_OBC_IT-2" host="localhost" port="20014" />
<node name="finish_IIS_OBC_UAT-1" host="localhost" port="20014" />
<node name="finish_IIS_OBC_PROD-2" host="localhost" port="20014" />
</root>
<强>输出强>:
<root>
<nodeGroup name="malden" nodes="APP_OBC_DEV-1,APP_OBC_IT-2" />
<nodeGroup name="finish" nodes="IIS_OBC_UAT-1,IIS_OBC_PROD-2" />
</root>