如何在XSLT中将元素移动到另一个转换元素?

时间:2017-02-09 08:29:28

标签: xml xslt

如何将'affiliation'元素移动到XSLT中'for-each'上下文中的'contrib'元素?

输入XML:

<article>
    <authors>Amrendra, Kumar; Mohan, Kumar</authors>
    <affiliation id="Amrendra, Kumar">Amrendra, Kumar</affiliation>
    <affiliation id="Mohan, Kumar">Mohan, Kumar</affiliation>
</article>

当前输出:

<contrib-group>
  <contrib>
    <string-name>Amrendra, Kumar</string-name>
  </contrib>
  <contrib>
    <string-name>Mohan, Kumar</string-name>
  </contrib>
  <aff id="Amrendra, Kumar">Amrendra, Kumar</aff>
  <aff id="Mohan, Kumar">Mohan, Kumar</aff>
</contrib-group>

XSLT代码:

<xsl:template match="authors">
    <xsl:choose>
        <xsl:when test="not(node())"/>
        <xsl:otherwise>
            <contrib-group>
                <xsl:for-each select="tokenize(., ';')">
                <contrib>
                    <string-name>
                        <xsl:value-of select="normalize-space(.)"/>
                    </string-name>
                </contrib>
                </xsl:for-each>
                <xsl:apply-templates select="../affiliation"/>
            </contrib-group>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

必需输出:(与aff / @ id和contrib /#pcdata匹配)

<contrib-group>
  <contrib>
    <string-name>Amrendra, Kumar</string-name>
    <aff id="Amrendra, Kumar">Amrendra, Kumar</aff>
  </contrib>
  <contrib>
    <string-name>Mohan, Kumar</string-name>
    <aff id="Mohan, Kumar">Mohan, Kumar</aff>
  </contrib>
</contrib-group>

当我尝试在contrib中应用'affiliation'元素时,它显示如下错误:

[Saxon-PE 9.5.1.7] XPTY0020: Cannot select the parent of the context node: the context item is not a node

2 个答案:

答案 0 :(得分:0)

假设authors字符串包含与affiliation/@id的值相同的标记,您可以这样做:

XSLT 2.0

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:key name="aff" match="affiliation" use="@id" />

<xsl:template match="article">
    <xsl:variable name="current-article" select="." />
    <contrib-group>
        <xsl:for-each select="tokenize(authors, '; ')">
            <contrib>
                <string-name>
                    <xsl:value-of select="."/>
                </string-name>
                <xsl:apply-templates select="key('aff', ., $current-article)[node()]"/>
            </contrib>
        </xsl:for-each>
    </contrib-group>
</xsl:template>

<xsl:template match="affiliation">
    <aff>
        <xsl:copy-of select="@* | node()" />
    </aff>
</xsl:template>

 </xsl:stylesheet>

获取所需的输出。

答案 1 :(得分:0)

<aff id="{.}">
    <xsl:value-of select="key('aff', ., $current-article)" />
</aff>
应该改变

以避免空格和缺失值

<aff id="{normalize-space(.)}">
    <xsl:value-of select="key('aff', normalize-space(.), $current-article)" />
</aff>