0

I have an XML file being sent to me from a third-party in the following format:

<Events>
  <COMPLETE>
    <TASK>1</TASK>
    <TIME>18:29</TIME>
    <USER>User1</USER>
    <DEP>OPPS</DEP>
  </COMPLETE>
  <PROGRESS>
    <TASK>2</TASK>
    <TIME>09:15</TIME>
    <USER>User1</USER>
    <DEP>OPPS</DEP>
  </PROGRESS>
  <PROGRESS>
    <TASK>2</TASK>
    <TIME>11:41</TIME>
    <USER>User2</USER>
    <DEP>COMS</DEP>
  </PROGRESS>
  <CLOSED>
    <TASK>3</TASK>
    <TIME>17:10</TIME>
    <DETAILS>
       <TIMECLOSED>17:01</TIMECLOSED>
       <CHECKEDBY>User9</CHECKEDBY>
    </DETAILS>
    <TAKEN>6.5</TAKEN>
    <USER>User8</USER>
    <DEP>FUNDS</DEP>
  </CLOSED>
  <COMPLETE>
    <TASK>4</TASK>
    <TIME>18:03</TIME>
    <USER>User3</USER>
    <DEP>COMS</DEP>
  </COMPLETE>
<Events>

Is there a way using XSLT to convert the child nodes of the Events element to be named Event and have an attribute called Name with the current child elements name. The output I was looking for is:

<Events>
  <Event Name='COMPLETE'>              <-- Changed
    <TASK>1</TASK>
    <TIME>18:29</TIME>
    <USER>User1</USER>
    <DEP>OPPS</DEP>
  </Event>
  <Event Name='PROGRESS'>              <-- Changed
    <TASK>2</TASK>
    <TIME>09:15</TIME>
    <USER>User1</USER>
    <DEP>OPPS</DEP>
  </Event>
  <Event Name='PROGRESS'>              <-- Changed
    <TASK>2</TASK>
    <TIME>11:41</TIME>
    <USER>User2</USER>
    <DEP>COMS</DEP>
  </PROGRESS>
  <Event Name='CLOSED'>                <-- Changed
    <TASK>3</TASK>
    <TIME>17:10</TIME>
    <DETAILS>
       <TIMECLOSED>17:01</TIMECLOSED>
       <CHECKEDBY>User9</CHECKEDBY>
    </DETAILS>
    <TAKEN>6.5</TAKEN>
    <USER>User8</USER>
    <DEP>FUNDS</DEP>
  </Event>
  <Event Name='COMPLETE'>              <-- Changed
    <TASK>4</TASK>
    <TIME>18:03</TIME>
    <USER>User3</USER>
    <DEP>COMS</DEP>
  </Event>
<Events>

I've looked online considerably and can not find how to do this. Many thanks!

2
  • 1
    What have you tried? Share your attempts and I am sure someone will be eager to comment/share a hint. Commented Oct 21, 2014 at 11:40
  • @Thomas Byme Take a look at this : stackoverflow.com/questions/4824843/… Commented Oct 21, 2014 at 11:43

2 Answers 2

1
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xi="http://www.w3.org/2001/XInclude">
  <xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>
  <xsl:template match="/Events">
    <xsl:element name="Events">
      <xsl:for-each select="*">
        <xsl:element name="Event">
          <xsl:attribute name="Name">
            <xsl:value-of select="local-name()"/>
          </xsl:attribute>
          <xsl:copy-of select="*"/>
        </xsl:element>
      </xsl:for-each>
    </xsl:element>
  </xsl:template>
</xsl:stylesheet>

This should do the job. A little bit more verbose than the previous answer, though.

Sign up to request clarification or add additional context in comments.

Comments

1

As an addition to an identity stylesheet:

<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="PROGRESS | CLOSED | COMPLETE">
  <Event Name="{local-name()}">
    <xsl:apply-templates />
  </Event>
</xsl:template>

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

</xsl:stylesheet>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.