为什么元素在转换后会出现两次?

时间:2010-08-05 13:33:57

标签: xml perl xslt

我正在使用Perl和XSL。我尝试将<Interval>的值更改为XML文件中的某个数字。我的XML看起来像这样:

<?xml version="1.0"?>
<Config>
    <Enabled>false</Enabled>
    <Interval>5</Interval>
</Config>

我的XSL看起来像这样:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        <xsl:template match="node()|@*">
    <xsl:copy>
    <xsl:apply-templates select="@*"/>
    <xsl:apply-templates/>
    </xsl:copy>
</xsl:template>
    <xsl:template match="/Config/Interval">
<xsl:element name="PollingInterval">
    <xsl:element name="Interval">77</xsl:element>
    </xsl:element>
</xsl:template>
</xsl:stylesheet>

问题是我的输出有两次元素<Interval>

<?xml version="1.0"?>
<Config>
    <Enabled>false</Enabled>
    <Interval><Interval>77</Interval></Interval>
</Config>

请帮忙。

2 个答案:

答案 0 :(得分:1)

此样式表:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="Interval/text()">77</xsl:template>
</xsl:stylesheet>

输出:

<Config>
    <Enabled>false</Enabled>
    <Interval>77</Interval>
</Config>

注意:如果您发布其他输入样本并描述绑定,我们可以向您展示如何提取新号码。

编辑:更短。

答案 1 :(得分:1)

  

问题是我的输出有   元素两次:

<?xml version="1.0"?> 
<Config> 
    <Enabled>false</Enabled> 
    <Interval><Interval>77</Interval></Interval>

</Config>

不正确!

在提供的XML文档上应用此转换时的输出是:

<Config>
    <Enabled>false</Enabled>
    <PollingInterval><Interval>77</Interval></PollingInterval>
</Config>

如果您想要删除任何一个元素,只需删除相应的<xsl:element> 指令。

例如:删除转化的<xsl:element name="PollingInterval">

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="@*"/>
            <xsl:apply-templates/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="/Config/Interval">
      <xsl:element name="Interval">77</xsl:element>
    </xsl:template>
</xsl:stylesheet>

,将其应用于提供的XML文档的结果为

<Config>
    <Enabled>false</Enabled>
    <Interval>77</Interval>
</Config>

我建议进一步简化转换,并匹配Interval的文本节点子项。这可能是最短最简单的解决方案

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

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

    <xsl:template match="Interval/text()">
      <xsl:text>77</xsl:text>
    </xsl:template>
</xsl:stylesheet>

应用于提供的XML文档

<Config>
    <Enabled>false</Enabled>
    <Interval>5</Interval>
</Config>

生成了想要的结果

<Config>
    <Enabled>false</Enabled>
    <Interval>77</Interval>
</Config>

如果您有许多Interval个元素,并且只希望将值5替换为77,那么除了身份规则之外的唯一模板应为:

<xsl:template match="Interval/text()[.=5]">
  <xsl:text>77</xsl:text>
</xsl:template>