首页 文章

xml上的部分xslt转换

提问于
浏览
0

我的样本xml:

<root> 
 <changeTag value="true"/>
 <a_original> name ="foo"</a_original>
 <b_original> name ="foo1"</b_original>

 <changeTag value = "false"/>
 <a_original> name ="foo1"</a_original>
 <b_original> name ="foo1"</b_original>
</root>

我希望在xslt中进行转换,它将转换'changeTag value = 2969065 '之后但不在' changeTag value = 2969066 '之后的节点 . I want all the nodes which are between changeValue value = " true " and changeValue value = " false " to be same as input xml 并在changeValue值= " false "之后执行所有转换

我的示例XML输出(预期)

<root> 
 <changeTag value="true"/>
 <a_original> name ="foo"</a_original>
 <b_original> name ="foo1"</b_original>

 <changeTag value = "false"/>
 <a_changed> name ="foo1"</a_changed>
 <b_changed> name ="foo1"</b_changed>
</root>

XSLT改变'a_original'

<xsl:template match = "a_original">
<a_changed>
<xsl:apply-templates select ="@* | node()">
</a_changed>
</xsl:template>

<xsl:template match = "b_original[@name='foo1']">
<b_changed>
<xsl:apply-templates select ="@* | node()">
</b_changed>
</xsl:template>

需要XSLT 1.0的解决方案 . 在我的实际XSLT文件中发生了很多不同的操作,例如删除和添加属性,删除和添加标签等, so its preferable if i can give a condition which mentions when to skip the nodes rather than the condition which mentions when to change.

1 回答

  • 1

    假设您的XML格式正确 . (即它是 <a_original name="foo"></a_original> 而不是 <a_original> name ="foo"</a_original> 然后你想要的模板匹配

    <xsl:template match="a_original[preceding-sibling::changeTag[1]/@value='false']">
    

    试试这个XSLT

    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
        <xsl:output method="xml" indent="yes" />
    
        <xsl:template match="a_original[preceding-sibling::changeTag[1]/@value='false']">
            <a_changed>
                <xsl:apply-templates select ="@* | node()" />
            </a_changed>
        </xsl:template>
    
        <xsl:template match="@*|node()">
            <xsl:copy>
                <xsl:apply-templates select="@*|node()"/>
            </xsl:copy>
        </xsl:template>
    </xsl:stylesheet>
    

    如果你想要一个更通用的模板,试试这样的......

    <xsl:template match="*[not(self::changeTag)][preceding-sibling::changeTag[1]/@value='false']">
        <xsl:element name="{substring-before(local-name(), '_original')}_changed">
            <xsl:apply-templates select ="@* | node()" />
        </xsl:element>
    </xsl:template>
    

    这会将任何此类元素从 _original 重命名为 _changed . 如果您的实际XML元素实际上没有后缀 _original ,您可能需要准确解释重命名的规则 .

    编辑:如果你不能提出重命名的通用规则,你可能不得不做这样的事情......

    <xsl:template match="*[not(self::changeTag)][preceding-sibling::changeTag[1]/@value='false']">
        <xsl:variable name="newName">
            <xsl:choose>
                <xsl:when test="self::a_original">a_changed</xsl:when>
                <xsl:when test="self::b_original[@name='foo1']">b_changed</xsl:when>
                <xsl:otherwise><xsl:value-of select="local-name()" /></xsl:otherwise>
            </xsl:choose>
        </xsl:variable>
        <xsl:element name="{$newName}">
            <xsl:apply-templates select ="@* | node()" />
        </xsl:element>
    </xsl:template>
    

相关问题