Arthur Eirich
Arthur Eirich

Reputation: 3638

Change xml attribute's value via xsl

I have a following xml document:

<xjdf:XJDF>
 <xjdf:AuditPool>
  <xjdf:Created TimeStamp="2013-09-03T12:07:16+02:00">
   <xjdf:Employee PersonalID="j.smith" Roles="Operator"/>
  </xjdf:Created>
 </xjdf:AuditPool>
</xjdf:XJDF>

In this document I would like to change the value of the TimeStamp attribute of the xjdf:Created element to be empty, like TimeStamp="". How can I do this using xsl? I tried following:

<xsl:template match="//xjdf:XJDF/xjdf:AuditPool/xjdf:Created/@TimeStamp">
    <xsl:attribute name="TimeStamp"/>
</xsl:template>

but without success.

Upvotes: 0

Views: 114

Answers (2)

Ian Roberts
Ian Roberts

Reputation: 122364

Your template will do the right thing but only if there is another template (such as an identity template) that causes it to be applied - on its own it won't fire because the default template rules never apply templates to attribute nodes. Here's an identity-based example

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
                xmlns:xjdf="urn:example-com:xjdf"> <!-- replace URI as appropriate -->

  <!-- identity template - copy everything as-is except where overridden -->
  <xsl:template match="@*|node()">
    <xsl:copy><xsl:apply-templates select="@*|node()" /></xsl:copy>
  </xsl:template>

  <!-- clear TimeStamp attribute -->
  <xsl:template match="xjdf:XJDF/xjdf:AuditPool/xjdf:Created/@TimeStamp">
    <xsl:attribute name="TimeStamp"/>
  </xsl:template>

</xsl:stylesheet>

Note that you don't need the leading // on the match pattern, and depending on the structure of the rest of your XML document you may not need all four levels of hierarchy - simply match="@TimeStamp" or match="xjdf:Created/@TimeStamp" may be sufficiently precise. If you want to alter other attributes you can simply add additional templates that match those, but if you want to add new attributes to an element that weren't there in the input then you will need to write a template that matches the element itself, for example

<xsl:template match="xjdf:Created">
  <xjdf:Created newAttribute="newValue">
    <xsl:apply-templates select="@*|node()" />
  </xjdf:Created>
</xsl:template>

Upvotes: 0

potame
potame

Reputation: 7905

You are not using xsl:attribute the right way, you must always put in an output element declaration (or there's something missing in the XSL you provide us). Moreover, you do not set any new value to the attribute.

Something like that should work

  <xsl:template match="//xjdf:XJDF/xjdf:AuditPool/xjdf:Created">
    <xjdf:Created>
      <xsl:attribute name="TimeStamp">
         (...the new attribute value here...)
      </xsl:attribute>
      <xsl:attribute name=" other_attribute "> 
         (...the other attribute value here...)
      </xsl:attribute>

      <xsl:apply-templates />
    </xjdf:Created>
  </xsl:template>

Upvotes: 1

Related Questions