2012-06-28 7 views
0

У меня есть следующий код XML.фильтрация XML-тегов с использованием XSLT

Вы заметите, что тег Описание повторяется, но с разными атрибутами.

Я использую XSLT, чтобы попытаться удалить тег 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> 

Если кто-то может мне точку в правильном направлении, я был бы очень благодарен.

Пол

+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()), а также любой из его атрибутов (@*).

+0

Ничего себе, что было быстро и так полезно. Большое спасибо. было именно тем, что я искал –

+0

@ user1488578: Не могли бы вы принять этот ответ (или любой другой ответ)), если ваша проблема решена? –

0

Вместо использования for-each и 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> 
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> 

Может быть, это поможет вам.

Marco

Смежные вопросы