我对使用XSL有点陌生。我正在尝试使用xsl将一个xml文件转换为另一个具有不同结构的xml文件。XML的输入部分如下:

<tag>
    <Keyword>Event: Some Text</Keyword>
    <Keyword>Group: Some Text</Keyword>
    <Keyword>Other: Some Text</Keyword>
</tag>

我希望期望的输出是:
<tag>
    <event> Some Text </event>
    <group> Some Text </group>
    <other> Some Text </other>
</tag>

我当前的xsl文件:
<xsl:for-each select="tag">
    <xsl:if test="starts-with(Keyword, 'Event: ')">
        <event>
          <xsl:value-of select="substring-after(Keyword, 'Event: ')"/>
        </event>
    </xsl:if>
    <xsl:if test="starts-with(Keyword, 'Group: ')">
        <group>
          <xsl:value-of select="substring-after(Keyword, 'Group: ')"/>
        </group>
    </xsl:if>
    <xsl:if test="starts-with(Keyword, 'Other: ')">
        <other>
          <xsl:value-of select="substring-after(Keyword, 'Other: ')"/>
        </other>
    </xsl:if>
</xsl:for-each>

当前输出仅显示事件节点,不显示其余节点:
<tag>
    <event> Some Text </event>
</tag>

我尝试在xsl中将“group”部分与“event”部分切换,但是由于输入xml中关键字节点的顺序,可能没有显示所有子节点。那么我如何读取所有的关键字节点并将它们转换为相应的新节点进行显示呢?

最佳答案

只有一个tag元素。你要遍历它的所有子对象:

<xsl:for-each select="tag/*">

    <xsl:if test="starts-with(., 'Event: ')">
        <event>
          <xsl:value-of select="substring-after(., 'Event: ')"/>
        </event>
    </xsl:if>
    <xsl:if test="starts-with(., 'Group: ')">
        <group>
          <xsl:value-of select="substring-after(., 'Group: ')"/>
        </group>
    </xsl:if>
    <xsl:if test="starts-with(., 'Other: ')">
        <other>
          <xsl:value-of select="substring-after(., 'Other: ')"/>
        </other>
    </xsl:if>
</xsl:for-each>

编辑:添加了另一个解决方案(使用@pierre的原始解决方案)。
注意xsl:element name属性的值被包装在{}中,因此它被计算为Attribute Value Template,而不是文本字符串:
<xsl:template match="tag">
<xsl:apply-templates select="Keyword"/>
</xsl:template>

<xsl:template match="Keyword">
<xsl:element name="{normalize-space(substring-before(.,':'))}">
 <xsl:value-of select="normalize-space(substring-after(.,':'))"/>
</xsl:element>
</xsl:template>

10-05 20:44
查看更多