XSLT - 这是使用可选元素进行XSLT转换的真正挑战

时间:2016-06-17 17:09:39

标签: xml xslt

我迷失了XSLT的艰难转型。

这是我的输入文件:

<block>
    <item>
        <name>item1</name>
        <place>place1</place>
    </item>

    <item>
        <name>item2</name>
        <comment>comment2</comment>
        <place>place2</place>
    </item>

    <item>
        <name>item3</name>
        <stick>stick3</stick>
       <place>place3</place>
    </item>
    ...
</block>

有任何阻止'项目':

  • 名称是必填项
  • 评论是可选的
  • 是可选的
  • 地方是强制性的
  • 订单非常重要(DTD文件验证此XML)!

我的问题:对于每个元素,我想插入一个元素 stick

<stick>default</stick>
  • 此元素标记必须位于元素评论之后(如果存在)或节点名称之后。
  • 如果元素已存在,则无需修改元素。

要恢复,我的输出文件必须是:

<block>
    <item>
        <name>item1</name>
        <stick>default</stick>
        <place>place1</place>
    </item>

    <item>
        <name>item2</name>
        <comment>comment2</comment>
        <stick>default</stick>
        <place>place2</place>
    </item>

    <item>
        <name>item3</name>
        <stick>stick3</stick>
        <place>place3</place>
    </item>
    ...
</block>

我已经尝试了很多XSLT转换,但不可能得到预期的结果: - (

有什么想法吗?

此致 Zido

1 个答案:

答案 0 :(得分:1)

那怎么样:

XSLT 1.0

<xsl:stylesheet version="1.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="*"/>

<!-- identity transform -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="item[not(stick)]/comment | item[not(stick or comment)]/name">
    <xsl:copy-of select="."/>
    <stick>default</stick>
</xsl:template>

</xsl:stylesheet>