为每个循环嵌套,从内部循环访问具有变量的外部元素 [英] Nested for-each loops, accessing outer element with variable from the inner loop

查看:192
本文介绍了为每个循环嵌套,从内部循环访问具有变量的外部元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图编写一个XSL,它将从源XML中输出一些特定的字段子集。这个子集将在转换时间通过使用包含字段名称的外部XML配置文档以及其他特定信息(如填充长度)来确定。



所以,这是两个 for-each 循环:




  • 从当前记录。



  • 我在在XSLT中,如何从嵌套循环中的外循环访问元素?外循环中的当前元素可以存储在 xsl:variable 。但是,我必须在内部循环内定义一个新的变量来获取字段名称。对于这个问题,问题产生了:是否有可能访问一个有两个变量的路径?

    b
    $ b

     < data> 
    < dataset>
    < record>
    < field1> value1< / field1>
    ...
    < fieldN> valueN< / fieldN>
    < / record>
    < / dataset>
    < dataset>
    < record>
    < field1> value1< / field1>
    ...
    < fieldN> valueN< / fieldN>
    < / record>
    < / dataset>
    < / data>

    我想要一个外部的XML文件,如下所示:

     < configuration> 
    < outputField order =1>
    < fieldName> field1< / fieldName>
    < fieldPadding> 25< / fieldPadding>
    < / outputField>
    ...
    < outputField order =N>
    < fieldName> fieldN< / fieldName>
    < fieldPadding> 10< / fieldPadding>
    < / outputField>
    < / configuration>

    到目前为止的XSL:

     < xsl:variable name =configselect =document('./ configuration.xml')/> 
    < xsl:for-each select =data / dataset / record>
    <! - 将当前记录存储在一个变量中 - >
    < xsl:variable name =recselect =。/>
    < xsl:variable name =paddingselect =fieldPadding/>

    <! - 这是麻烦 - >
    < xsl:variable name =valueselect =$ rec / $ field/>

    < xsl:call-template name =append-pad>
    < xsl:with-param name =padVarselect =$ value/>
    < xsl:with-param name =lengthselect =$ padding/>
    < / xsl:call-template>

    < / xsl:for-each>
    < xsl:value-of select =$ newline/>
    < / xsl:for-each>

    我对XSL相当陌生,所以这可能是一个荒谬的问题,也是明显的错误(即重复一次任务可以在开始的内部循环)。我会很感激如何从外部循环元素中选择字段值的任何提示,当然,打开更好的方法来处理这个任务。

    你的样式表看起来很好。只要表达式 $ rec / $ field 没有意义,因为不能以这种方式组合两个节点集合/序列。相反,您应该使用 name()函数比较元素的名称。如果我正确地理解了你的问题,像这样的东西应该工作:

    $ p $ < xsl:variable name =configselect =文件( './ configuration.xml文件')/>
    < xsl:for-each select =data / dataset / record>
    < xsl:variable name =recselect =。/>
    ...
    ...
    < / xsl:for-each>
    < xsl:value-of select =$ newline/>
    < / xsl:for-each>

    变量字段在本示例中不是必需的。您还可以使用函数 current()来访问内部循环的当前上下文节点:

     < xsl:variable name =valueselect =$ rec / * [name(。)= current()/ fieldName]/> 


    I'm trying to write an XSL that will output a certain subset of fields from the source XML. This subset will be determined at transformation time, by using an external XML configuration document containing the field names, and other specific information (such as the padding length).

    So, this is two for-each loops:

    • The outer one iterates over the records to access their fields record by record.
    • The inner one iterates over the configuration XML document to grab the configured fields from the current record.

    I've seen in In XSLT how do I access elements from the outer loop from within nested loops? that the current element in the outside loop can be stored in an xsl:variable. But then I've got to define a new variable inside the inner loop to get the field name. Which yields to the question: Is it possible to access a path in which there are two variables ?

    For instance, the source XML document looks like:

    <data>
        <dataset>
            <record>
                <field1>value1</field1>
                ...
                <fieldN>valueN</fieldN>
            </record>
        </dataset>
        <dataset>
            <record>
                <field1>value1</field1>
                ...
                <fieldN>valueN</fieldN>
            </record>
        </dataset>
    </data>
    

    I'd like to have an external XML file looking like:

    <configuration>
        <outputField order="1">
            <fieldName>field1</fieldName>
            <fieldPadding>25</fieldPadding>
        </outputField>
        ...
        <outputField order="N">
            <fieldName>fieldN</fieldName>
            <fieldPadding>10</fieldPadding>
        </outputField>
    </configuration>
    

    The XSL I've got so far:

    <xsl:variable name="config" select="document('./configuration.xml')"/>
    <xsl:for-each select="data/dataset/record">
        <!-- Store the current record in a variable -->
        <xsl:variable name="rec" select="."/>
        <xsl:for-each select="$config/configuration/outputField">
            <xsl:variable name="field" select="fieldName"/>
            <xsl:variable name="padding" select="fieldPadding"/>
    
            <!-- Here's trouble -->
            <xsl:variable name="value" select="$rec/$field"/>
    
            <xsl:call-template name="append-pad">
                <xsl:with-param name="padChar" select="$padChar"/>
                <xsl:with-param name="padVar" select="$value"/>
                <xsl:with-param name="length" select="$padding"/>
            </xsl:call-template>
    
        </xsl:for-each>
        <xsl:value-of select="$newline"/>
    </xsl:for-each>
    

    I'm quite new to XSL, so this might well be a ridiculous question, and the approach can also be plain wrong (i.e. repeatig inner loop for a task that could be done once at the beggining). I'd appreciate any tips on how to select the field value from the outer loop element and, of course, open to better ways to approach this task.

    解决方案

    Your stylesheet looks almost fine. Just the expression $rec/$field doesn't make sense because you can't combine two node sets/sequences this way. Instead, you should compare the names of the elements using the name() function. If I understood your problem correctly, something like this should work:

    <xsl:variable name="config" select="document('./configuration.xml')"/>
    <xsl:for-each select="data/dataset/record">
        <xsl:variable name="rec" select="."/>
        <xsl:for-each select="$config/configuration/outputField">
            <xsl:variable name="field" select="fieldName"/>
            ...
            <xsl:variable name="value" select="$rec/*[name(.)=$field]"/>
            ...    
        </xsl:for-each>
        <xsl:value-of select="$newline"/>
    </xsl:for-each>
    

    Variable field is not required in this example. You can also use function current() to access the current context node of the inner loop:

    <xsl:variable name="value" select="$rec/*[name(.)=current()/fieldName]"/>
    

    这篇关于为每个循环嵌套,从内部循环访问具有变量的外部元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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