strippin xml中的元素,并使用xslt基于特定条件替换元素的值

时间:2013-07-31 10:41:50

标签: xslt

我遇到了需要从输入XML中删除元素的问题:

<message 
    xmlns="http://www.origoservices.com" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>
<m_control>
    <control_timestamp>2013-06-06T14:55:37</control_timestamp>
    <initiator_id>ASL</initiator_id>
</m_control>
<m_content>
    <b_control>
        <quote_type>Single Company</quote_type>
        <quote_or_print>Quote And Print</quote_or_print>
        <generic_quote_ind>Yes</generic_quote_ind>
        <tpsdata>
            <tps_quote_type>Comparison</tps_quote_type>
        </tpsdata>
    </b_control>
    <application>
     <product>
        <tpsdata>
            <service_type>QuickQuote</service_type>
            <quote_type>Standard</quote_type>
        </tpsdata>
      </product>
    </application>
</m_content>
</message>

如果<tps_quote_type>'Comparison',则将<quote_type>的值更改为'Comparison',并删除<tpsdata>字段。输出应如下所示。

<message 
    xmlns="http://www.origoservices.com" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>
<m_control>
     <control_timestamp>2013-06-06T14:55:37</control_timestamp>
     <initiator_id>ASL</initiator_id>
</m_control>
<m_content>
    <b_control>
         <quote_type>Comparison</quote_type>
         <quote_or_print>Quote And Print</quote_or_print>
         <generic_quote_ind>Yes</generic_quote_ind>
    </b_control>
   <application>
       <product>
          <tpsdata>
            <service_type>QuickQuote</service_type>
            <quote_type>Standard</quote_type>
          </tpsdata>
    </product>
    </application>
</m_content>
</message>

到目前为止,我已尝试过这个XSLT,但我不知道如何从输出中删除<tpsdata>字段。有人可以帮助我吗?

<xsl:stylesheet 
    version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:dp="http://www.datapower.com/extensions"
    xmlns:fn="http://www.w3.org/2005/xpath-functions"
    xmlns:date="http://exslt.org/dates-and-times" 
    extension-element-prefixes="dp"
>
    <xsl:output method="xml" indent="yes"/>

    <xsl:template match="*">
        <!-- identity with closing tags -->
        <xsl:element name="{name()}">
            <xsl:apply-templates select="@*|node()"/>
        </xsl:element>
    </xsl:template>

    <xsl:variable name="quoteType">
       <xsl:value-of select="/*[namespace-uri()='http://www.origoservices.com' and  local- name()='message']/*[namespace-uri()='http://www.origoservices.com' and local-name() ='m_content']/*[namespace-uri()='http://www.origoservices.com' and local-name()='b_control']/*[namespace-uri()='http://www.origoservices.com' and local-name()='quote_type']"/>
    </xsl:variable>

    <xsl:variable name="tpsQuoteType">
        <xsl:value-of select="/*[namespace-uri()='http://www.origoservices.com' and local-name()='message']/*[namespace-uri()='http://www.origoservices.com' and local-name()='m_content']/*[namespace-uri()='http://www.origoservices.com' and local-name()='b_control']/*[namespace-uri()='http://www.origoservices.com' and local-name()='tpsdata']/*[namespace-uri()='http://www.origoservices.com' and local-name()='tps_quote_type']"/>
    </xsl:variable>

    <xsl:template match="/*[namespace-uri()='http://www.origoservices.com' and local-name()='message']/*[namespace-uri()='http://www.origoservices.com' and local-name()='m_content']/*[namespace-uri()='http://www.origoservices.com' and local-name()='b_control']/*[namespace-uri()='http://www.origoservices.com' and local-name()='quote_type']">
        <xsl:choose>
            <xsl:when test="$tpsQuoteType = 'Comparison' ">
                <xsl:copy>
                    <xsl:copy-of select="@*"/>
                    <xsl:text>Comparison</xsl:text>
                </xsl:copy>
            </xsl:when>
            <xsl:otherwise>
                <xsl:copy>
                    <xsl:apply-templates select="@*|node()"/>
                </xsl:copy>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>

    <xsl:template match="*|comment()|processing-instruction()">
        <xsl:copy>
            <xsl:copy-of select="@*|namespace::*"/>
            <xsl:apply-templates/>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

2 个答案:

答案 0 :(得分:2)

也许您注意到使用命名空间处理这些元素有点痛苦。只需将http://www.origoservices.com命名空间添加到XSLT中,痛苦就会消失。

<xsl:stylesheet 
    version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:o="http://www.origoservices.com" 
    xmlns:dp="http://www.datapower.com/extensions"
    xmlns:fn="http://www.w3.org/2005/xpath-functions"
    xmlns:date="http://exslt.org/dates-and-times" 
    extension-element-prefixes="dp"
    exclude-result-prefixes="fn date"
>
    <xsl:output method="xml" indent="yes"/>

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

    <xsl:template match="o:b_control/o:quote_type[../o:tpsdata/o:tps_quote_type = 'Comparison']">
        <xsl:copy>
            <xsl:apply-templates select="@*" />
            <xsl:text>Comparison</xsl:text>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="o:tpsdata[o:tps_quote_type = 'Comparison']" />

</xsl:stylesheet>

注释

  • 大部分“管道工程”都没有必要。
  • 模板匹配表达式不需要是完整路径。
  • 使用匹配表达式而不是<xsl:choose>来确定要更改的元素。
  • 从基本身份模板开始,根据需要使用更具体的模板覆盖它。这使得您的生活比使用修改后的身份模板更容易。
  • 使用空模板删除特定元素。

答案 1 :(得分:0)

<xsl:stylesheet version="1.0" extension-element-prefixes="dp" exclude-result-prefixes="dp regexp fn dpconfig" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:dp="http://www.datapower.com/extensions" xmlns:dpconfig="http://www.datapower.com/param/config" xmlns:dpfunc="http://www.datapower.com/extensions/functions" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:regexp="http://exslt.org/regular-expressions" >

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

</xsl:template>


<xsl:template match="*[local-name()='tpsdata']/*[local-name()='quote_type']">
    <xsl:message dp:priority="debug"> Found quote_type </xsl:message> 
        <xsl:variable name = "First"> 
                <xsl:value-of select="/*[local-name()='message']/*[local-name()='m_content']/*[local-name()='b_control']/*[local-name()='tpsdata']/*[local-name()='tps_quote_type']/text()"/>
        </xsl:variable>

        <xsl:variable name = "Second">
                <xsl:value-of select = "."/>
        </xsl:variable>
        <xsl:message dp:priority="debug"> Second:<xsl:value-of select = "$Second"/></xsl:message> 
        <xsl:message dp:priority="debug"> First: <xsl:value-of select = "$First"/> </xsl:message>

    <xsl:choose>
        <xsl:when test="$Second = $First">
            <xsl:message dp:priority="debug"> Stand and Comp are same </xsl:message>
                <xsl:copy>
                    <xsl:apply-templates select="@*|node()"/>
                </xsl:copy>
        </xsl:when>


        <xsl:otherwise>
            <xsl:message dp:priority="debug"> Stand and Comp are different </xsl:message>
                <xsl:copy>
                    <xsl:value-of select="regexp:replace(*[local-name()='quote_type'],'','',$First)"/>
                </xsl:copy>
        </xsl:otherwise>

    </xsl:choose>


</xsl:template>
    <xsl:template match="*[local-name()='b_control']/*[local-name()='tpsdata']"/>

</xsl:stylesheet>