Exclude attribute from a specific xml element using xslt
Asked Answered
H

3

18

I am new in xslt. I have the following problem. I need within an xml, to remove a specific attribute (theAttributein the example) from a specific element (e.g. div). i.e.

<html>
   <head>...</head>
   <body>
      <div id="qaz" theAtribute="44">
      </div>
      <div id ="ddd" theAtribute="4">
         <div id= "ggg" theAtribute="9">
         </div>
      </div>
      <font theAttribute="foo" />
   </body>
</html>

to become

<html>
   <head>...</head>
   <body>
      <div id="qaz">
      </div>
      <div id ="ddd">
         <div id= "ggg">
         </div>
      </div>
      <font theAttribute="foo" />
   </body>
</html>

Where attribute theAtribute has been removed. I found this, http://www.biglist.com/lists/xsl-list/archives/200404/msg00668.html based on which i made attempts to find the proper solution.

i.e. <xsl:template match="@theAtribute" />

Which removed it from the whole document... and others like match, if choose, etc. Nothing worked.. :-( can you please help me on this? it sound trivial to me, but with xslt, i cannot cope at all...

Thank you all in advance

Hanghangar answered 25/6, 2010 at 7:54 Comment(1)
if you want the code to be formatted, you can highlight the code and click the "010101" button at the top of the edit panel, or indent the text 4 spaces.Roue
R
39

What is not working? Do you want the same content, just without the @theAtribute?

If so, make sure your stylesheet has the empty template for @theAtribute, but also has an identity template that copies everything else into the output:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <!--empty template suppresses this attribute-->
    <xsl:template match="@theAtribute" />
    <!--identity template copies everything forward by default-->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

If you only want to suppress certain @theAtribute, then you can make the match criteria more specific. For instance, if you only wanted to remove that attribute from the div who's @id="qaz", then you could use this template:

<xsl:template match="@theAtribute[../@id='qaz']" />

or this template:

<xsl:template match="*[@id='qaz']/@theAtribute" />

If you want to remove @theAttribute from all div elements, then change the match expression to:

<xsl:template match="div/@theAtribute" />
Roue answered 25/6, 2010 at 11:18 Comment(3)
Hello, these two i had found as well i am afraid but they are not helpful. the first one removes the "theAtribute" from everywhere (divs, body, font, etc tags). The second approach removes from everywhere the @theAtribute from all nodes with id=qaz. Is there a way for me to write <xsl:template match="@theAtribute[../@nodename='div']" /> ?? what i need, is a mix of these two i think, but i cannot figure out the format due to mi ignorance on xslt. I which to remove the theAtribute from all divs and only from divs.Hanghangar
I see. I didn't realize in the description that you specifically wanted to exclude div/@theAtribute. I've updated the answer. If your XML elements are bound to a namespace, you may need to declare the namespace in your XSLT, or use an XPATH statement that ignores the namespace and matches on the local-name (i.e. *[local-name()='div']/@theAtribute)Roue
For followers, if you want to exclude multiples it can be something like match="@theAtribute | @otherAttribute" and they can be full xpath style expressions as well...Jeromejeromy
H
15

inside the select, you can exclude (or include,) the attribute, using the name function.

For example, <xsl:copy-of select="@*[name(.)!='theAtribute']|node()" />

Highams answered 11/5, 2011 at 8:19 Comment(1)
This worked well for me, I wanted to replace one attribute and then copy the rest, and this expression worked well for "the rest"Karyokinesis
V
0
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"  
xmlns:xs="http://www.w3.org/2001/XMLSchema" >

        <xsl:output method="xml" encoding="UTF-8" indent="yes" />
        <xsl:param name="status"/>

        <!--If attribute is present change it -->
        <xsl:template match="@status" >
            <xsl:attribute name="status" select="$status"/>
        </xsl:template>
        <!-- If attribute is not present add it al last position -->
        <xsl:template match="row[ not( @status ) ]" >
            <xsl:copy>
                <xsl:apply-templates select="@*"/>
                <!-- put attribute in the last position -->
                <xsl:attribute name="status" select="$status"/>
                <xsl:apply-templates select="node()"/>
            </xsl:copy>
        </xsl:template>

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

    </xsl:stylesheet>

I have a xml like:

<row  attribute1="value" >some stuff</row> 

and I'm adding at end of list of attributes a status from an outside value.

\saxonee\bin\Transform.exe -xsl:my_script.xsl -s:rows.xml status="completed"

<row current_run="2019-07-29 19:00" status="completed">
Vocalism answered 1/8, 2019 at 13:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.