xml上的部分xslt转换

时间:2017-06-27 15:53:42

标签: xml xslt xpath xslt-1.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中进行转换,这将转换在&lt; changetag值=&#34; true&#34;之后的节点。 &#39;但不是在&#39; changeTag value =&#34; false&#34; &#39 ;. 我想要所有在changeValue值=&#34之间的节点;真的&#34;和changeValue值=&#34;假&#34;与输入xml相同并在changeValue value =&#34之后执行所有转换;假&#34;

我的示例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更改&#39; a_original&#39;

<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文件中有很多不同的操作发生,例如删除和添加属性,删除和添加标签等,所以如果我能提供一个条件提及何时跳过节点而不是提到何时改变的条件。

1 个答案:

答案 0 :(得分: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>