删除<xsl:if>语句?正在寻找替代方案

时间:2018-03-07 22:18:10

标签: xml xslt

我是XSLT的新手。我编写了以下内容,测试是否存在/Config/Service/Groups/Group[x],如果存在,则会添加Route并将Group[x]/name的值用于dGroup。

<xsl:if test="/Config/Service/Groups/Group[2]">
    <Route>
        <match>.*1202.*</match>
        <type>E</type>
        <dGroup>
            <xsl:value-of select="/Config/Service/Groups/Group[2]/name"/>
        </dGroup>
    </Route>
</xsl:if>
<xsl:if test="/Config/Service/Groups/Group[3]">
    <Route>
        <match>.*1203.*</match>
        <type>E</type>
        <dGroup>
            <xsl:value-of select="/Config/Service/Groups/Group[3]/name"/>
        </dGroup>
    </Route>
</xsl:if>
<xsl:if test="/Config/Service/Groups/Group[3]">
    <Route>
        <match>1311</match>
        <type>A</type>
        <dGroup>
            <xsl:value-of select="/Config/Service/Groups/Group[3]/name"/>
        </dGroup>
    </Route>
</xsl:if>
<xsl:if test="/Config/Service/Groups/Group[4]">
    <Route>
        <match>2311</match>
        <type>A</type>
        <dGroup>
            <xsl:value-of select="/Config/Service/Groups/Group[4]/name"/>
        </dGroup>
    </Route>
</xsl:if>
<xsl:if test="/Config/Service/Groups/Group[5]">
    <Route>
        <match>3311</match>
        <type>A</type>
        <dGroup>
            <xsl:value-of select="/Config/Service/Groups/Group[5]/name"/>
        </dGroup>
    </Route>
</xsl:if>

我必须检查并添加9个路由,只有9个这些组(如果存在)。每个组可能有多个路由,每个路由中都有不同的匹配元素。使用如此多的if语句似乎有点笨拙,但我无法弄清楚如何更好地编写它,因为匹配元素和Group一样。

在XSLT中有更合适的方法吗?

这是xml:

<Config>
    <Service>
        <Groups>
            <Group>
                <name>cs</name>
                <extension>501</extension>
            </Group>
            <Group>
                <name>ab</name>
                <extension>602</extension>
            </Group>
            <Group>
                <name>bu</name>
                <extension>703</extension>
            </Group>
            <Group>
                <name>ch</name>
                <extension>804</extension>
            </Group>
        </Groups>
    </Service>
</Config>

1 个答案:

答案 0 :(得分:0)

一种方法是使用具有每个Group映射的数据岛。另一个是使用单独的文件来存储这些映射。

在这个例子中,我选择了前一个 该代码使用position()元素的Group进行映射。当然还有其他可能性。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:gKey="http://gkey.com">
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>

    <!-- Data island with mapping (could be moved to a separate file -->
    <gKey:keys>
        <key num="2" match=".*1202.*" type="E" />
        <key num="3" match=".*1203.*" type="E" />
        <key num="3" match="1311"     type="A" />
        <key num="4" match="2311"     type="A" />
        <key num="5" match="3311"     type="A" />
    </gKey:keys>

    <xsl:template match="/">
        <!-- Iterate over all <Group>s -->
        <xsl:for-each select="Config/Service/Groups/Group">
            <xsl:variable name="pos" select="position()" />
            <xsl:variable name="nam" select="/Config/Service/Groups/Group[$pos]/name" />
            <!-- Iterate over all keys for this <Group> -->
            <xsl:for-each select="document('')/*/gKey:keys/key[@num = $pos]">
                <!-- Compose the <Route> element -->
                <Route>
                    <match><xsl:value-of select="@match" /></match>
                    <type><xsl:value-of  select="@type" /></type>
                    <dGroup>
                        <xsl:value-of select="$nam"/>
                    </dGroup>
                </Route>  
            </xsl:for-each>
        </xsl:for-each>
    </xsl:template>  

</xsl:stylesheet>

<强>输出:

<Route>
    <match>.*1202.*</match>
    <type>E</type>
    <dGroup>Groupie Two</dGroup>
</Route>
<Route>
    <match>.*1203.*</match>
    <type>E</type>
    <dGroup>Groupie Three</dGroup>
</Route>
<Route>
    <match>1311</match>
    <type>A</type>
    <dGroup>Groupie Three</dGroup>
</Route>
<Route>
    <match>2311</match>
    <type>A</type>
    <dGroup>Groupie Four</dGroup>
</Route>
<Route>
    <match>3311</match>
    <type>A</type>
    <dGroup>Groupie Five</dGroup>
</Route>