嵌套for-each循环,使用内部循环中的变量访问外部元素

Xav*_*ica 14 xslt variables foreach xpath

我正在尝试编写一个XSL,它将从源XML输出某个字段子集.通过使用包含字段名称的外部XML配置文档和其他特定信息(例如填充长度),将在转换时确定此子集.

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

  • 外部循环遍历记录以按记录访问其字段.
  • 内部迭代遍历配置XML文档以从当前记录中获取已配置的字段.

我在In XSLT中看到如何从嵌套循环中访问外部循环中的元素?外部循环中的当前元素可以存储在xsl:variable.但是我必须在内部循环中定义一个新变量来获取字段名称.产生问题的原因是:是否可以访问存在两个变量的路径?

例如,源XML文档如下所示:

<data>
    <dataset>
        <record>
            <field1>value1</field1>
            ...
            <fieldN>valueN</fieldN>
        </record>
    </dataset>
    <dataset>
        <record>
            <field1>value1</field1>
            ...
            <fieldN>valueN</fieldN>
        </record>
    </dataset>
</data>
Run Code Online (Sandbox Code Playgroud)

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

<configuration>
    <outputField order="1">
        <fieldName>field1</fieldName>
        <fieldPadding>25</fieldPadding>
    </outputField>
    ...
    <outputField order="N">
        <fieldName>fieldN</fieldName>
        <fieldPadding>10</fieldPadding>
    </outputField>
</configuration>
Run Code Online (Sandbox Code Playgroud)

我到目前为止的XSL:

<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>
Run Code Online (Sandbox Code Playgroud)

我对XSL很新,所以这可能是一个荒谬的问题,而且这种方法也可能是完全错误的(即重新启动内部循环,可以在开始时执行一次任务).我很欣赏有关如何从外部循环元素中选择字段值的任何提示,当然,还有更好的方法来处理此任务.

Mar*_*tin 14

你的样式表看起来很好.只是表达式$rec/$field没有意义,因为你不能用这种方式组合两个节点集/序列.相反,您应该使用该name()函数比较元素的名称.如果我理解你的问题,这样的事情应该有效:

<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>
Run Code Online (Sandbox Code Playgroud)

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

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