如何正确地用逗号分隔两个数据字段?

时间:2017-04-21 14:16:31

标签: xslt concatenation

我在XML中有以下两个数据字段:

 <datafield tag="036C">
<subfield code="a">Ėkonomičeskaja politika Rossii v uslovijach globalʹnoj turbulentnosti</subfield>
<subfield code="y">meždunarodnyj finansovo-ėkonomičeskij forum - 2014 (24-26 nojabrja, Moskva)</subfield>
<subfield code="c">Finansovyj universitet pri pravitelʹstve Rossijskoj Federacii</subfield>
<subfield code="l">tom 3</subfield></datafield>

<datafield tag="036C" occurrence="01">
<subfield code="a">Materialy zasedanij kruglych stolov</subfield>
<subfield code="l">Čast 2</subfield>
</datafield>

我试图用XSLT中的逗号连接它们:

<xsl:variable name="pica036C"
                        select="recordData/record/datafield[@tag='036C']" />

    <xsl:variable name="titleFrom036C">

                          <xsl:for-each select="$pica036C">
                            <xsl:value-of select="concat(datafield[@tag='036c'][1], ', ', datafield[@tag='036c'][2])" />    
</xsl:for-each>
</xsl:variable>

问题是我得到了太多逗号。第一个数据字段始终位于第一个数据字段036c(,Ėkonomičeskaja)之前。它应该被删除。第二个是在两个数据域之间 - 这是正确的。如何删除第一个逗号?

实际值: ,ĖkonomičeskajapolitikaRossii v uslovijach global'noj turbulentnosti:meždunarodnyjfinansovo-ėkonomičeskijforum - 2014(24-26 nojabrja,Moskva); tom 3,Materialy zasedanij kruglych stolov; Čast2

必须(第一个逗号被删除,“tom 3”之后的逗号仍然存在): Ėkonomičeskajapolitika Rossii v uslovijach global'noj turbulentnosti:meždunarodnyjfinansovo-ėkonomičeskijforum - 2014(24-26 nojabrja,Moskva); tom 3,Materialy zasedanij kruglych stolov; Čast2

2 个答案:

答案 0 :(得分:2)

你像一个程序程序员一样思考。不要使用xsl:for-each,其中XSL对节点集成员的自然迭代处理就足够了。如果你想在给定节点的转换中进行特殊处理(例如没有前导逗号),那么考虑给它自己的模板。

这是一个相当简单的方法,你可以应用这些原则来实现你想要的东西(我不得不猜测你省略的一些细节):

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="text" />
  <xsl:strip-space elements="*"/>

  <xsl:template match="record">
    <!-- a different set of datafields could be selected instead by applying
         this template with a different value for this parameter: -->
    <xsl:param name="tag" select="'036C'"/>

    <xsl:apply-templates select="datafield[@tag=$tag][1]"/>
    <xsl:apply-templates select="datafield[@tag=$tag][position() > 1]" mode="concat" />
  </xsl:template>

  <xsl:template match="datafield" mode="concat">
    <!-- prepend a ", " to the default transformation of this element -->
    <xsl:text>, </xsl:text><xsl:apply-templates select="."/>
  </xsl:template>

  <xsl:template match="datafield">
    <xsl:apply-templates select="subfield[@code='a']"/>
    <xsl:apply-templates select="subfield[@code='y']">
      <xsl:with-param name="delim" select="' : '"/>
    </xsl:apply-templates>
    <xsl:apply-templates select="subfield[@code='l']">
      <xsl:with-param name="delim" select="' ; '"/>
    </xsl:apply-templates>
  </xsl:template>

  <xsl:template match="subfield">
    <xsl:param name="delim"/>
    <xsl:value-of select="$delim"/>
    <xsl:value-of select="."/>
  </xsl:template>

</xsl:stylesheet>

答案 1 :(得分:2)

代码中实际包含pica036C变量的内容是什么? 它是一个包含2个项目的数组,取自datafield个标记。

现在,实际上包含第一项:

  • 文本节点 - 打开 datafield 标记之间的空格和 \ n 和第一个打开子字段标记。
  • 第一个子字段标记。
  • 另一个文本节点 - 第一个关闭子字段之间的空格和 \ n 标记和第二个打开子字段标记。
  • 等等。

所以datafield[@tag='036c'][1]指的是只包含“白色”的节点 字符。要连接的下一个项目是', ',这就是您所看到的 作为“初始”逗号。

还要记住,在<xsl:for-each select="$pica036C">循环内部 .指的是pica036C数组中的当前元素。

因此,如果您想获得subfield,请编写subfield,而不要使用。{1}} 父节点,仅存在于源文档中,但不存在于pica036C

我的建议:

  1. 以这种方式创建pica036C变量:

    <xsl:variable name="pica036C" as="text()*">
      <xsl:for-each select="recordData/record/datafield[@tag='036C']">
        <xsl:value-of select="string-join(subfield, '&#xA;')"/>
      </xsl:for-each>
    </xsl:variable>
    

    你还得到一个包含2个项目的数组,每个项目包含连接的子字段 来自各个数据域,但没有之间的空白文本节点 它们。

    string-join的第二个参数,而不是&#xA;(换行符) 可以是一个空格(对你的最终结果更好)。

  2. 以这种方式创建titleFrom036C

    <xsl:variable name="titleFrom036C" select=
        "concat($pica036C[1], ',&#xA;', $pica036C[2])" />
    

    然后,当你使用例如<xsl:value-of select="$titleFrom036C"/> 你会得到:

    • 第一份出版物的完整标题。
    • 逗号和换行符。
    • 第二份出版物的完整标题。