2016-10-14 7 views
0

У меня есть следующий входной XML-файл:XSLT-1,0: Изменение значения атрибута

$ cat data.xml 
<?xml version="1.0" encoding="UTF-8" standalone="no"?> 
<root> 
    <outer id="0" status="FAIL" > 
    <nested status="FAIL" > 
     <inner status="FAIL" > 
     <innermost status="FAIL" /> 
     </inner> 
    </nested> 
    </outer> 
    <outer id="1" status="VOID"> 
    <nested status="VOID" > 
     <inner status="VOID" > 
     <innermost status="VOID" /> 
     <innermost status="VOID" /> 
     </inner> 
    </nested> 
    </outer> 
</root> 

Этот XSL-файл, как предполагается изменить значение атрибута status в VOID если FAIL:

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

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

    <xsl:template match="*[@status = 'FAIL']"> 
    <!--xsl:template match="*/@status[. = 'FAIL']"--> 
    <xsl:copy> 
     <xsl:attribute name="status">VOID</xsl:attribute> 
     <!--xsl:attribute name="newattribute">NEW VALUE</xsl:attribute--> 
     <xsl:apply-templates select="@*|node()"/> 
    </xsl:copy> 
    </xsl:template> 

</xsl:stylesheet> 

Однако, это ничего не меняет. Я знаю, что соответствует правильным узлам, потому что я могу добавить новый атрибут на этапе, когда изменение должно произойти:

... 
<!-- This works fine --> 
<xsl:attribute name="newattribute">NEW VALUE</xsl:attribute> 
... 

Как я могу изменить значение status?

ответ

3

Однако, это ничего не меняет.

Собственно, это неправда. Ваш код работает просто отлично, и это:

<xsl:attribute name="status">VOID</xsl:attribute> 

действительно создает новый атрибут с именем status со значением "VOID".


Проблема в том, что произойдет дальше. Эта инструкция:

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

копирует существующие атрибуты контекстного элемента - и поскольку один из этих атрибутов также называют status, он переписывает status атрибут вы только сейчас созданы.


Вы могли бы решить эту проблему, изменив порядок так:

<xsl:template match="*[@status = 'FAIL']"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*"/> 
     <xsl:attribute name="status">VOID</xsl:attribute> 
     <xsl:apply-templates select="node()"/> 
    </xsl:copy> 
</xsl:template> 

но более простое решение, чтобы сосредоточиться на атрибуте:

XSLT 1,0

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

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

<xsl:template match="@status[. = 'FAIL']"> 
    <xsl:attribute name="status">VOID</xsl:attribute> 
</xsl:template> 

</xsl:stylesheet> 
+0

It работает сейчас, спасибо. – nautical

+0

«Добавление атрибута к элементу заменяет любой существующий атрибут этого элемента тем же самым расширенным именем». (Https://www.w3.org/TR/xslt#creating-attributes) – LarsH

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