【问题标题】:Generate all combinations of values生成所有值组合
【发布时间】:2018-03-16 13:47:03
【问题描述】:

我经常需要生成测试数据文件,其中包含 3 或 4 个字段的所有可能值。这是一个包含 3 个值的示例 XML(但通常还有更多...)

 <xml>
  <dataset  name="service">
    <row name="Tracked" code="T"/>
    <row name="Untracked" code="U"/>
  </dataset>

   <dataset name="terminal">
    <row name="New York" code="JFK"/>
    <row name="Newark" code="EWR"/>
    <row name="Chicago" code="ORD" />
  </dataset>

  <dataset name="lodgement">
    <row name="Melbourne" code="MEL" />
    <row name="Perth" code="PER" />
    <row name="Sydney" code="SYD"/>
  </dataset>
</xml>

我希望创建以下输出

<xml>
    <row service='T' terminal='JFK' lodgement='MEL'/>
    <row service='T' terminal='JFK' lodgement='PER'/>
    <row service='T' terminal='JFK' lodgement='SYD'/>

    <row service='T' terminal='EWR' lodgement='MEL'/>
    <row service='T' terminal='EWR' lodgement='PER'/>
    <row service='T' terminal='EWR' lodgement='SYD'/>

    <row service='T' terminal='ORD' lodgement='MEL'/>
    <row service='T' terminal='ORD' lodgement='PER'/>
    <row service='T' terminal='ORD' lodgement='SYD'/>

    <row service='U' terminal='JFK' lodgement='MEL'/>
    <row service='U' terminal='JFK' lodgement='PER'/>
    <row service='U' terminal='JFK' lodgement='SYD'/>

    <row service='U' terminal='EWR' lodgement='MEL'/>
    <row service='U' terminal='EWR' lodgement='PER'/>
    <row service='U' terminal='EWR' lodgement='SYD'/>

    <row service='U' terminal='ORD' lodgement='MEL'/>
    <row service='U' terminal='ORD' lodgement='PER'/>
    <row service='U' terminal='ORD' lodgement='SYD'/>
</xml> 

我有这个 XSL 工作,但对于这种情况,它完全是硬编码的,我正在寻找一个通用的解决方案,它适用于任意数量的数据集。

<?xml version='1.0'?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:variable name='servicerow' select='//dataset[@name="service"]/row'/>
<xsl:variable name='terminalrow' select='//dataset[@name="terminal"]/row'/>
<xsl:variable name='lodgementrow' select='//dataset[@name="lodgement"]/row'/>

<xsl:template match='/'>
    <xml>
        <xsl:for-each select='$servicerow'>
            <xsl:variable name='service' select='@code'/>
            <xsl:for-each select='$terminalrow'>
                <xsl:variable name='terminal' select='@code'/>
                <xsl:for-each select='$lodgementrow'>
                    <xsl:variable name='lodgement' select='@code'/>
                    <xsl:element name='row'>
                        <xsl:attribute name='service'><xsl:value-of select='$service'/></xsl:attribute>
                        <xsl:attribute name='terminal'><xsl:value-of select='$terminal'/></xsl:attribute>
                        <xsl:attribute name='lodgement'><xsl:value-of select='$lodgement'/></xsl:attribute>
                    </xsl:element>
                </xsl:for-each> <!-- lodgement -->
            </xsl:for-each> <!-- terminal -->
        </xsl:for-each> <!-- service -->
    </xml>
</xsl:template>

</xsl:stylesheet>

【问题讨论】:

    标签: xml xslt


    【解决方案1】:

    这对你有用吗....

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    
    <xsl:output method="xml" indent="yes" />
    
    <xsl:template match='/xml'>
        <xml>
            <xsl:apply-templates select="dataset[1]/row" />
        </xml>
    </xsl:template>
    
    <xsl:template match="row">
        <xsl:param name="prev" />
        <xsl:choose>
            <xsl:when test="../following-sibling::dataset">
                <xsl:choose>
                    <xsl:when test="$prev">
                        <xsl:apply-templates select="../following-sibling::dataset[1]/row">
                           <xsl:with-param name="prev" select=". | $prev" />
                        </xsl:apply-templates>
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:apply-templates select="../following-sibling::dataset[1]/row">
                           <xsl:with-param name="prev" select="." />
                        </xsl:apply-templates>
                    </xsl:otherwise>
                </xsl:choose>
            </xsl:when>
            <xsl:otherwise>
                <row>
                    <xsl:for-each select="$prev|.">
                        <xsl:attribute name="{../@name}">
                            <xsl:value-of select="@code" />
                        </xsl:attribute>
                    </xsl:for-each>
                </row>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
    
    </xsl:stylesheet>
    

    【讨论】:

    • 次要,如果只有 1 个数据集,$prev 是空的,它搞砸了 .NET 解析器。我添加了一个检查以查看 xsl 中是否存在 $prev:否则
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-05
    • 2022-11-18
    • 1970-01-01
    • 2017-04-01
    • 2016-01-07
    相关资源
    最近更新 更多