tags:

views:

27

answers:

1

I have the following XML:

<DEVICEMESSAGES> 
  <VERSION xml="1" checksum="" revision="0" envision="33050000" device="" />
  <HEADER id1="0001" id2="0001" content="Nasher[&lt;messageid&gt;]: &lt;!payload&gt;" />
  <MESSAGE level="7" parse="1" parsedefvalue="1" tableid="15" id1="24682" id2="24682" eventcategory="1003010000" content="Access to &lt;webpage&gt; was blocked due to its category (&lt;info&gt; by &lt;hostname&gt;)" />
</DEVICEMESSAGES> 

I am using the following XSLT:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt; 
  <xsl:output method="text"/> 
  <xsl:strip-space elements="*"/> 

  <xsl:template match="DEVICEMESSAGES/HEADERS"> 
    <xsl:value-of select="@id2"/>,<xsl:text/> 
    <xsl:value-of select="@content"/>,<xsl:text/> 
    <xsl:text>&#xa;</xsl:text> 
  </xsl:template> 
</xsl:stylesheet> 

I get the following output:

0001 ,           Nasher[<messageid>]: <!payload>

whereas I need the column headings, too:

id2,             content 
0001 ,           Nasher[<messageid>]: <!payload>
+1  A: 

If DEVICEMESSAGES is the document element and you have repeating MESSAGE elements, then this should work:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
  <xsl:output method="text"/>
  <xsl:strip-space elements="*"/>

  <xsl:template match="DEVICEMESSAGES">
        <xsl:text>id2,content,&#xa;</xsl:text>
        <xsl:apply-templates/>
  </xsl:template>

  <xsl:template match="DEVICEMESSAGES/HEADER">
    <xsl:value-of select="@id2"/>,<xsl:text/>
    <xsl:value-of select="@content"/>,<xsl:text/>
    <xsl:text>&#xa;</xsl:text>
  </xsl:template>

</xsl:stylesheet>

If you have a different document element, then adjust the template to match on that.

For instance, if the document element is doc and you had 1 to N number of DEVICEMESSAGES elements:

<doc>

<DEVICEMESSAGES>
  <VERSION xml="1" checksum="" revision="0" envision="33050000" device="" />
  <HEADER id1="0001" id2="0001" content="Nasher[&lt;messageid&gt;]: &lt;!payload&gt;" />
  <MESSAGE level="7" parse="1" parsedefvalue="1" tableid="15" id1="24682" id2="24682" eventcategory="1003010000" content="Access to &lt;webpage&gt; was blocked due to its category (&lt;info&gt; by &lt;hostname&gt;)" />
</DEVICEMESSAGES>

<DEVICEMESSAGES>
  <VERSION xml="1" checksum="" revision="0" envision="33050000" device="" />
  <HEADER id1="0002" id2="0002" content="Nasher[&lt;messageid&gt;]: &lt;!payload&gt;" />
  <MESSAGE level="7" parse="1" parsedefvalue="1" tableid="15" id1="24682" id2="24682" eventcategory="1003010000" content="Access to &lt;webpage&gt; was blocked due to its category (&lt;info&gt; by &lt;hostname&gt;)" />
</DEVICEMESSAGES>

</doc>

then you could use this:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
  <xsl:output method="text"/>
  <xsl:strip-space elements="*"/>

  <xsl:template match="doc">
        <xsl:text>id2,content,&#xa;</xsl:text>
        <xsl:apply-templates/>
  </xsl:template>

  <xsl:template match="DEVICEMESSAGES/HEADER">
    <xsl:value-of select="@id2"/>,<xsl:text/>
    <xsl:value-of select="@content"/>,<xsl:text/>
    <xsl:text>&#xa;</xsl:text>
  </xsl:template>

</xsl:stylesheet>

EDIT: Another alternative that uses the template match of the root node and does not need to know what the document element is:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
  <xsl:output method="text"/>
  <xsl:strip-space elements="*"/>

  <xsl:template match="/">
        <xsl:text>id2,content,&#xa;</xsl:text>
        <xsl:apply-templates/>
  </xsl:template>

  <xsl:template match="DEVICEMESSAGES/HEADER">
    <xsl:value-of select="@id2"/>,<xsl:text/>
    <xsl:value-of select="@content"/>,<xsl:text/>
    <xsl:text>&#xa;</xsl:text>
  </xsl:template>

</xsl:stylesheet>
Mads Hansen
Or perhaps template match="*" and have that template explicitly call match on DEVICEMESSAGE/HEADER.
Nat
@Nat - Probably `/*` to restrict the match, so as not to match on any element in the document except the document element. Or just add a template match for the root node. Lots of ways to do it. It helps to see a full sample of the data structure.
Mads Hansen
Oops. Better that way.
Nat