1

t:mult3FXSLtestFunc-curry.xsl文件中的示例为例,我对其稍作更改,以便前 2 个参数是序列。这些序列在咖喱时似乎会丢失任何空的项目。

<xsl:function name="foo:bar" as="xs:anyAtomicType">
        <xsl:param name="headers" as="xs:string*"/>
        <xsl:param name="row" as="xs:anyAtomicType*"/>
        <xsl:param name="column" as="xs:string"/>
        <xsl:message select="$column"/>
        <xsl:message select="count($row)"/>
        <xsl:value-of select="$row[index-of($headers, $column)]"/>
</xsl:function>

这在直接调用或前 2 个参数被柯里化时工作正常,前提是序列没有row空(字符串)项。但是,如果其中一个row项目为空(例如,考虑 CSV 样式的输入,其中列的值如下test_col_two所示是可选的。请注意,标题是强制性的,并且取自 CSV 的第一行):

<xsl:variable name="row" select="tokenize(.,',')"/>
<xsl:variable name="rw" select="foo:bar($headers, $row)"/>
<xsl:message select="$rw"/>
<xsl:variable name="a" select="f:apply($rw,'test_col_one')"/>
<xsl:variable name="b" select="f:apply($rw,'test_col_two')"/>
<xsl:variable name="c" select="f:apply($rw,'test_col_three')"/>
<xsl:message select="concat($a,$b,$c)"/>

如果test_col_two为空,变量b将包含 的值test_col_three,而不是test_col_two

我是否误解了这个例子,或者这是 FXSL 的问题?

我可以看到 XML 输出foo:bar($headers, $row)确实包含表示空字符串的空元素,因此至少最初从我看到的内容中正确捕获了信息。

完整代码如下。

<xsl:import href="fxsl-xslt2/f/func-curry.xsl"/>
<foo:bar/>
<xsl:function name="foo:bar" as="node()">
    <xsl:sequence select="document('')/*/foo:bar[1]"/>
</xsl:function>
<xsl:function name="foo:bar" as="xs:anyAtomicType">
    <xsl:param name="headers" as="xs:string*"/>
    <xsl:param name="row" as="xs:anyAtomicType*"/>
    <xsl:param name="column" as="xs:string"/>
    <xsl:message select="$column"/>
    <xsl:message select="count($row)"/>
    <xsl:value-of select="$row[index-of($headers, $column)]"/>
</xsl:function>
<xsl:function name="foo:bar" as="node()">
    <xsl:param name="headers" as="xs:string*"/>
    <xsl:sequence select="f:curry(foo:bar(), 3, $headers)"/>
</xsl:function>
<xsl:function name="foo:bar" as="node()">
    <xsl:param name="headers" as="xs:string*"/>
    <xsl:param name="row" as="xs:anyAtomicType*"/>
    <xsl:sequence select="f:curry(foo:bar(), 3, $headers, $row)"/>
</xsl:function>
<xsl:template match="foo:bar" mode="f:FXSL">
    <xsl:param name="arg1" as="xs:string*"/>
    <xsl:param name="arg2" as="xs:anyAtomicType*"/>
    <xsl:param name="arg3" as="xs:string"/>
    <xsl:sequence select="foo:bar($arg1,$arg2,$arg3)"/>
</xsl:template>
4

1 回答 1

1

看着

 <xsl:function name="int:makeArg" as="element()">
    <xsl:param name="arg1"/>
    <arg>
      <xsl:choose>
        <xsl:when test="exists($arg1[2])">
          <xsl:attribute name="s"/>

          <xsl:for-each select="$arg1">
            <e t="{f:type(.)}"><xsl:sequence select="."/></e>
          </xsl:for-each>
        </xsl:when>
        <xsl:otherwise>
          <xsl:attribute name="t" select="f:type($arg1)"/>
          <xsl:sequence select="$arg1"/>
        </xsl:otherwise>
      </xsl:choose>
    </arg>
  </xsl:function>

  <xsl:function name="int:getArg">
    <xsl:param name="pargNode" as="element()*"/>

    <xsl:sequence select=
     "if(not($pargNode/@s))
        then 
           if(not($pargNode/@t) or $pargNode/@t = 'xml:node')
              then $pargNode/node()
              else
                f:apply(f:Constructor($pargNode/@t), $pargNode/node() )
        else
          for $varg in $pargNode/e/node()
            return  
               if(not($varg/../@t) or $varg/../@t = 'xml:node')
                  then $varg
                  else
                     f:apply(f:Constructor($varg/../@t), $varg )
     "
    />
  </xsl:function>

其中参数是用它创建int:makeArg和处理的,int:getArg它似乎用原始 arg 的值作为内容 ( )makeArg设置一个元素,然后像它一样期望一个子节点。但是,如果您有一个内部包含空字符串的序列,那么我认为这种方法会吞下空字符串,因为with 不会在元素中构造任何子节点,然后with显然无法找到该参数。所以看起来FXSL那里有一些缺陷,也许是重写e<e t="{f:type(.)}"><xsl:sequence select="."/></e>getArgefor $varg in $pargNode/e/node()xsl:sequence select="''"egetArge/node()

          for $varg in $pargNode/e/node()
            return  
               if(not($varg/../@t) or $varg/../@t = 'xml:node')
                  then $varg
                  else
                     f:apply(f:Constructor($varg/../@t), $varg )

作为

          for $varg in $pargNode/e
            return  
               if(not($varg/@t) or $varg/@t = 'xml:node')
                  then $varg/node()
                  else
                     f:apply(f:Constructor($varg/@t), $varg )

就够了。希望 Dimitre Novatchev @DimitreNovaatchev 作为库的作者可以告诉您更多有关此的信息。

于 2018-03-19T14:59:47.500 回答