Jesper Bloch-Hansen
Jesper Bloch-Hansen

Reputation: 25

XSLT renaming element with attribute value?

I have this XML:

<PARTY>
          <PARTY_ID type="buyer_specific">XXXXXX</PARTY_ID>
          <PARTY_ID type="gln">YYYYYYYYYYYY</PARTY_ID>
          <PARTY_ROLE>buyer</PARTY_ROLE>
</PARTY>

And I need the elements PARTY_ID to be named different, preferably set to the same as type

So preferred result would be:

<PARTY>
          <buyer_specific>XXXXXX</buyer_specific>
          <gln>YYYYYYYYYYYY</gln>
          <PARTY_ROLE>buyer</PARTY_ROLE>
</PARTY>

I know this is probably a easy fix, but I am really new at XSLT..... thx for your patience and help!

Upvotes: 1

Views: 47

Answers (2)

Dimitre Novatchev
Dimitre Novatchev

Reputation: 243579

As simple as this:

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

  <xsl:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>
  
  <xsl:template match="PARTY_ID[@type]">
     <xsl:element name="{@type}"><xsl:apply-templates/></xsl:element>
  </xsl:template>
</xsl:stylesheet>

When this transformation is applied on the provided XML document:

<PARTY>
    <PARTY_ID type="buyer_specific">XXXXXX</PARTY_ID>
    <PARTY_ID type="gln">YYYYYYYYYYYY</PARTY_ID>
    <PARTY_ROLE>buyer</PARTY_ROLE>
</PARTY>

The wanted, correct result is produced:

<PARTY>
   <buyer_specific>XXXXXX</buyer_specific>
   <gln>YYYYYYYYYYYY</gln>
   <PARTY_ROLE>buyer</PARTY_ROLE>
</PARTY>

Explanaion:

  1. Using the identity rule to copy every node "as-is"

  2. Overriding the identity rule with a more specific one matching any PARTY_ID element that has a type attribute

  3. Using an <xsl:element> instruction with AVL (Attribute Value Template) for the name of the element -- to be constructed from the value of the type attribute of the current node.

Upvotes: 0

Jesper Bloch-Hansen
Jesper Bloch-Hansen

Reputation: 25

I have managed to get something that is ok for the task at hand working:

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

<xsl:template match="PARTY_ID[@type]">
      <xsl:element name="{@type}">
        <xsl:apply-templates/>
      </xsl:element>
    </xsl:template>

<xsl:template match="*">    
        <xsl:element name="{local-name()}" namespace="http://www.opentrans.org/XMLSchema/2.1">
        <xsl:apply-templates/>
    </xsl:element>  
</xsl:template>

</xsl:stylesheet>

Not ideal, but it works... Thank you for reading!

Upvotes: 1

Related Questions