0

我有以下 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> 

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

保罗

4

3 回答 3

0

不要使用for-eachand value-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> 
于 2012-06-28T13:37:51.650 回答
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()) 以及它的任何属性 ( @*)。

于 2012-06-28T13:18:10.770 回答
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>

也许它可以帮助你。

马可

于 2012-06-28T13:42:46.903 回答