从XSLT中的函数返回元素的值类型

时间:2018-09-14 06:38:25

标签: xslt-2.0

这是我的XML

<report>
    <format-inputs>
        <narrative-entity-ids>
            <entity id="28495795" type-cdf-meaning="DIAGNOSES"/>
            <entity id="28495741" type-cdf-meaning="DIAGNOSES"/>
            <entity id="28495471" type-cdf-meaning="DIAGNOSES"/>
        </narrative-entity-ids>
    </format-inputs>
</report> 

我正在commonFunction.xslt中创建一个函数

<xsl:function name="cdocfx:createEntityIdList" >
        <xsl:param name="formatInputsNodes"/>

        <xsl:if test="fn:exists(n:report/n:format-inputs)"
        <xsl:variable name="entityIdList" as="element()*">
            <xsl:for-each select="$formatInputsNodes/n:narrative-entity-ids/n:entity">
                <Item><xsl:value-of select="@id"/></Item>
            </xsl:for-each>
        </xsl:variable>
       </xsl:if>

        <xsl:copy-of select="$entityIdList"/>

    </xsl:function>

我正在其他包含commonFunction.xslt的xslt文件中调用此函数

<xsl:variable name="entityIdList" select="cdocfx:createEntityIdList(n:report/n:format-inputs)"/>

</xsl:variable>

我的问题是变量entityIdList应该是元素的值类型,但是它具有文档节点类型,我该如何实现呢?

1 个答案:

答案 0 :(得分:0)

请提供最少但完整的XML输入示例,包括您拥有的XSLT,所需的输出以及与您一起遇到的确切错误消息的XML示例。

我目前不确定我要理解什么,如果构造element()*类型的变量,则似乎要构造一系列元素节点。但是,任何xsl:value-of都只会在文本节点中输出所选项目的字符串值,因此,如果只想输出字符串值,则不清楚为什么要首先构造元素。如果您构造节点并想输出它们,请使用xsl:copy-ofxsl:sequence,而不要使用xsl:value-of

要显示编写返回一个元素序列的函数的两个示例(即,其结果为element()*类型),我设置了https://xsltfiddle.liberty-development.net/3NzcBtE,它具有两个函数

  <xsl:function name="mf:ex1">
      <xsl:param name="input" as="element()*"/>
      <xsl:for-each select="$input">
          <item>{ @id }</item>
      </xsl:for-each>
  </xsl:function>

  <xsl:function name="mf:ex2">
      <xsl:param name="input" as="element()*"/>
      <xsl:variable name="elements" as="element()*">
          <xsl:for-each select="$input">
              <item>{ @id }</item>
          </xsl:for-each>          
      </xsl:variable>
      <xsl:sequence select="$elements"/>
  </xsl:function>

第一个简单地直接在函数体内构造一些结果元素,这样结果就是元素节点的序列。第二个函数使用在变量中构造元素节点序列的方法,然后从函数中返回该变量值的正确方法是使用xsl:sequence

不清楚您认为发布的代码在document-node()节点上的哪个位置。

请注意

    <xsl:choose>
        <xsl:when test="fn:exists($formatInputsNodes/n:narrative-entity-ids)">
            <xsl:for-each select="$formatInputsNodes/n:narrative-entity-ids/n:entity">
                <Item><xsl:value-of select="@id"/></Item>
            </xsl:for-each>
        </xsl:when>

    </xsl:choose>

可以简化为

      <xsl:for-each select="$formatInputsNodes/n:narrative-entity-ids/n:entity">
             <Item><xsl:value-of select="@id"/></Item>
      </xsl:for-each>

现在您已经介绍了至少格式正确的XML输入和一些XSLT代码段(不幸的是格式不正确,并且似乎使用了命名空间,尽管所示的XML输入不使用名称空间)在这里是尝试将其变形为工作样本

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:cdocfx="http://example.com/cdox-functions"
    exclude-result-prefixes="#all"
    version="3.0">

  <xsl:function name="cdocfx:createEntityIdList" >
    <xsl:param name="formatInputsNodes"/>

    <xsl:variable name="entityIdList" as="element()*">
        <xsl:for-each select="$formatInputsNodes/narrative-entity-ids/entity">
            <Item><xsl:value-of select="@id"/></Item>
        </xsl:for-each>
    </xsl:variable>


    <xsl:copy-of select="$entityIdList"/>

  </xsl:function>

  <xsl:variable name="entityIdList" select="cdocfx:createEntityIdList(report/format-inputs)"/>

  <xsl:output method="text"/>

  <xsl:template match="/">
     <xsl:value-of select="$entityIdList instance of element()*, $entityIdList" separator=", "/>
  </xsl:template>

</xsl:stylesheet>

https://xsltfiddle.liberty-development.net/pPqsHTW/1

那里的检查$entityIdList instance of element()*的输出是true,所以我不确定为什么您说您有一个文档节点。