使用XSLT过滤XML标记

时间:2012-06-28 13:07:00

标签: xml xslt ssis xls

我有以下XML代码。

您会注意到标签描述重复,但具有不同的属性。

我正在使用XSLT尝试删除带有enabled属性的Description标记。

<Batch>
- <Promotion>
  <LastUpdated>2008-01-22T11:58:05+00:00</LastUpdated> 
  <MajorVersion>1</MajorVersion> 
  <MinorVersion>29</MinorVersion> 
  <PromotionID>000873</PromotionID> 
  <Description enabled="1">*P* Free Mistletoe</Description> 
  <Description country="GB" language="en" variant="">WANTED LINE 1</Description>
 </Promotion>
 <Promotion>
   <LastUpdated>2008-01-22T11:58:05+00:00</LastUpdated> 
   <MajorVersion>1</MajorVersion> 
   <MinorVersion>29</MinorVersion> 
   <PromotionID>000874</PromotionID> 
   <Description enabled="1">*P* Free Mistletoe</Description> 
   <Description country="GB" language="en" variant="">WANTED LINE 2</Description>
 </Promotion> 
</batch>

这是我想要的,还有其他标签,它是一个删除 基于我想要解决的属性的行。

- <promotions>
-   <promotion>
      <promotionID>000873</promotionID> 
      <description country="GB" language="en" variant="">WANTED LINE 1</description>
    </promotion>
-   <promotion> 
      <promotionID>000874</promotionID> 
      <description country="GB" language="en" variant="">WANTED LINE 2</description>
    </promotion> 
  </promotions>

我使用的XSLT代码是

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>

<xsl:template match="node()|@*">
  <xsl:copy>
  <xsl:apply-templates select="node()|@*"/>
  </xsl:copy>
</xsl:template>
<xsl:template match="//promotion/Description[@country='GB']"/> 
<xsl:template match="/"> 

<promotions> 
<xsl:for-each select="Batch/Promotion">  
  <promotion>
    <promotion_id><xsl:value-of select="PromotionID"/></promotion_id>    
    <description><xsl:value-of select="Description"/></description>
  </promotion>
</xsl:for-each>   
</promotions>   
</xsl:template>
</xsl:stylesheet> 

如果有人能指出我正确的方向,我将非常感激。

3 个答案:

答案 0 :(得分:0)

通常,为了删除元素,您必须指定一个没有任何内容的模板。在您的情况下,这可能是:

<xsl:template match="/Batch/Promotion/Description[@enabled = '1']"/>

但是,在您的XSLT代码中,您可以构建自己的<description>元素。为了准确获取所需<Description>元素的值,请在<xsl:value-of>元素中选择它:

<description><xsl:value-of select="Description[@country = 'GB']"/></description>

这是您在问题中描述的内容,但是您的预期结果代码暗示您已经想要复制<Description>元素的属性?在这种情况下,我会使用<xsl:copy-of>

来寻找此解决方案
<description><xsl:copy-of select="Description[@country = 'GB']/node()|Description[@country = 'GB']/@*"/></description>

它复制<Description>元素(node())的全部内容及其任何属性(@*)。

答案 1 :(得分:0)

请考虑使用更多模板,而不是使用for-eachvalue-of

请注意以下代码中的注释。

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

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

<!-- instead of an explicit for-each, just apply templates -->
<xsl:template match="/">
<promotions><xsl:apply-templates/></promotions>
</xsl:template>

<!-- We ignore Batch, but apply templates on contents -->
<xsl:template match="Batch"><xsl:apply-templates/></xsl:template>

<!-- Rename the Promotion element -->
<xsl:template match="Promotion">
<promotion><xsl:apply-templates/></promotion>
</xsl:template>

<!-- we make an exception for subelements of Promotion: here we delete by default -->
<!-- we give this template a lower priority so we can override it with other rules -->
<xsl:template match="Promotion/*" priority="-0.5"/>

<!-- The templates that follow are exceptions to the "Promotion/*" no-copy template: -->

<!-- Only copy Description elements with the right country code -->
<!-- Remember that the "Promotion/*" template will delete any other Description elements for us -->
<xsl:template match="Description[@country='GB']">
<description><xsl:apply-templates/></description>
</xsl:template>

<!-- Rename the PromotionID element -->
<xsl:template match="PromotionID">
   <promotion_id><xsl:apply-templates/></promotion_id>
</xsl:template>

</xsl:stylesheet> 

答案 2 :(得分:0)

尝试使用<xsl:value-of select="Description[not(string(@enabled))]"/>代替<xsl:value-of select="Description"/>

完整示例:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="node()|@*">
    <xsl:copy>
        <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
</xsl:template>
<xsl:template match="//promotion/Description[@country='GB']"/>
<xsl:template match="/">
    <promotions>
        <xsl:for-each select="Batch/Promotion">
            <promotion>
                <promotion_id>
                    <xsl:value-of select="PromotionID"/>
                </promotion_id>
                <description>
                    <xsl:value-of select="Description[not(string(@enabled))]"/>
                </description>
            </promotion>
        </xsl:for-each>
    </promotions>
</xsl:template>

结果是:

<?xml version="1.0" encoding="UTF-16"?>
    <promotions>
    <promotion>
        <promotion_id>000873</promotion_id>
        <description>WANTED LINE 1</description>
    </promotion>
    <promotion>
        <promotion_id>000874</promotion_id>
        <description>WANTED LINE 2</description>
    </promotion>
</promotions>

也许它可以帮到你。