Unwanted element data (without elements) appears in xslt - xslt

I am trying to apply a transformation to generate an rdf document. My source xml contains an element that I want to ignore, but the output (generated via SAP's transformation test tool) includes the (concatenated!) texts of the elements from SYSINFO.
I have tried several variations (such as xsl:apply-templates select="asx:abap/asx:/values/CT" )
but then I get no output at all. Hmm. Have spent several hours trying different things and researching, but have gotten nowhere. Any help really appreciated. John
Here is my sample xml (fragment)
<?xml version="1.0" encoding="utf-8"?>
<asx:abap xmlns:asx="http://www.sap.com/abapxml"version="1.0">
<asx:values>
<SYSINFO>
<SERVER_NAME>sapserver06</SERVER_NAME>
<SYSTEM_ID>ECC</SYSTEM_ID>
<SAP_RELEASE>701</SAP_RELEASE>
<SYS_NR>00</SYS_NR>
<CLIENT>800</CLIENT>
<EXE_USER>XXX</EXE_USER>
<LOGON_LANGUAGE>E</LOGON_LANGUAGE>
<DATE>2013-04-09</DATE>
<TIME>12:06:58</TIME>
<TIMEZONE>CST</TIMEZONE>
<OPERATING_SYSTEM>Windows NT</OPERATING_SYSTEM>
<LICENSE_NUMBER>YYY</LICENSE_NUMBER>
<SAP_CUSTOMER>ZZZ</SAP_CUSTOMER>
<CLIENT_CATEGORY>C</CLIENT_CATEGORY>
<LANGUAGES_INSTALLED>JED</LANGUAGES_INSTALLED>
</SYSINFO>
<CT>
<item>
<ID>1</ID>
<TABNAME>T000</TABNAME>
<FIELDNAME>ADRNR</FIELDNAME>
<KEYFLAG/>
<ROLLNAME>CHAR10</ROLLNAME>
</item>
.....
</CT>
</asx:values>
</asx:abap>
Here is the transformation
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:sap="http://www.sap.com/sapxsl" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:sap_coda="http://www.sapmantics.com/sap_coda#" version="1.0">
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<rdf:RDF>
<xsl:apply-templates/>
</rdf:RDF>
</xsl:template>
<xsl:template>
<xsl:for-each select="//item">
<rdf:Description>
<xsl:attribute name="rdf:about">
<xsl:value-of select="TABNAME"/>
</xsl:attribute>
<rdf:type rdf:resource="http://www.sapmantics.com/sap_coda#ctable"/>
<sap_coda:t2f>
<rdf:Description>
<xsl:attribute name="rdf:about">
<xsl:value-of select="FIELDNAME"/>
</xsl:attribute>
<rdf:type rdf:resource="http://www.sapmantics.com/sap_coda#cfield"/>
<xsl:if test="KEYFLAG=X">
<sap_coda:keyflag>X</sap_coda:keyflag>
</xsl:if>
</rdf:Description>
</sap_coda:t2f>
</rdf:Description>
</xsl:for-each>
</xsl:template>
</xsl:transform>
And finally, here is the output:
<?xml version="1.0" encoding="utf-16"?>
sapserver06ECC70100800XXXE2013-04-0917:21:50CSTWindowsNTYYYZZZCJED
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:sap_coda="http://www.sapmantics.com/sap_coda#">
<rdf:Description rdf:about="T000">
<rdf:type rdf:resource="http://www.sapmantics.com/sap_coda#ctable"/>....

The concatenation of your <SYSINFO/> text nodes can be explained by the default handing for element nodes:
http://www.w3.org/TR/xslt#built-in-rule
I don't know which XSLT processor you are using, but I am surprised that your //item handler wasn't flagged for lacking a #match attribute. You can update it with the following, and it will handle each <item/> element in document order:
<xsl:template match="item">
<rdf:Description>
To keep your SYSINFO content from being included in your RDF (if that is your intent), update your root template with the following:
<rdf:RDF>
<xsl:apply-templates select="//item"/>
</rdf:RDF>
-----------EDIT--------------------------
With this input
<?xml version="1.0" encoding="utf-8"?>
<asx:abap xmlns:asx="http://www.sap.com/abapxml">
<asx:values>
<SYSINFO>
<SERVER_NAME>sapserver06</SERVER_NAME>
<SYSTEM_ID>ECC</SYSTEM_ID>
<SAP_RELEASE>701</SAP_RELEASE>
<SYS_NR>00</SYS_NR>
<CLIENT>800</CLIENT>
<EXE_USER>XXX</EXE_USER>
<LOGON_LANGUAGE>E</LOGON_LANGUAGE>
<DATE>2013-04-09</DATE>
<TIME>12:06:58</TIME>
<TIMEZONE>CST</TIMEZONE>
<OPERATING_SYSTEM>Windows NT</OPERATING_SYSTEM>
<LICENSE_NUMBER>YYY</LICENSE_NUMBER>
<SAP_CUSTOMER>ZZZ</SAP_CUSTOMER>
<CLIENT_CATEGORY>C</CLIENT_CATEGORY>
<LANGUAGES_INSTALLED>JED</LANGUAGES_INSTALLED>
</SYSINFO>
<CT>
<item>
<ID>1</ID>
<TABNAME>T000</TABNAME>
<FIELDNAME>ADRNR</FIELDNAME>
<KEYFLAG/>
<ROLLNAME>CHAR10</ROLLNAME>
</item>
</CT>
</asx:values>
</asx:abap>
and this stylesheet
<?xml version="1.0" encoding="UTF-8"?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:sap="http://www.sap.com/sapxsl"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:sap_coda="http://www.sapmantics.com/sap_coda#"
version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<rdf:RDF>
<xsl:apply-templates select="//item"/>
</rdf:RDF>
</xsl:template>
<xsl:template match="item[parent::CT]">
<rdf:Description>
<xsl:attribute name="rdf:about">
<xsl:value-of select="TABNAME"/>
</xsl:attribute>
<rdf:type rdf:resource="http://www.sapmantics.com/sap_coda#ctable"/>
<sap_coda:t2f>
<rdf:Description>
<xsl:attribute name="rdf:about">
<xsl:value-of select="FIELDNAME"/>
</xsl:attribute>
<rdf:type rdf:resource="http://www.sapmantics.com/sap_coda#cfield"/>
<xsl:if test="KEYFLAG=X">
<sap_coda:keyflag>X</sap_coda:keyflag>
</xsl:if>
</rdf:Description>
</sap_coda:t2f>
</rdf:Description>
</xsl:template>
<xsl:template match="item[parent::FOO]"/>
<xsl:template match="item"/>
</xsl:transform>
I get this output from Saxon-EE 9.4.0.3:
<?xml version="1.0" encoding="UTF-8"?>
<rdf:RDF xmlns:sap="http://www.sap.com/sapxsl"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:sap_coda="http://www.sapmantics.com/sap_coda#">
<rdf:Description rdf:about="T000">
<rdf:type rdf:resource="http://www.sapmantics.com/sap_coda#ctable"/>
<sap_coda:t2f>
<rdf:Description rdf:about="ADRNR">
<rdf:type rdf:resource="http://www.sapmantics.com/sap_coda#cfield"/>
</rdf:Description>
</sap_coda:t2f>
</rdf:Description>
</rdf:RDF>
and this output from xstlproc:
<?xml version="1.0"?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:sap="http://www.sap.com/sapxsl" xmlns:sap_coda="http://www.sapmantics.com/sap_coda#">
<rdf:Description rdf:about="T000">
<rdf:type rdf:resource="http://www.sapmantics.com/sap_coda#ctable"/>
<sap_coda:t2f>
<rdf:Description rdf:about="ADRNR">
<rdf:type rdf:resource="http://www.sapmantics.com/sap_coda#cfield"/>
</rdf:Description>
</sap_coda:t2f>
</rdf:Description>
</rdf:RDF>

Related

Compare data of 2 xmls in xslt

I am new to XSL. Hence please help me with the below.
I have 2 xmls. I have to do the following in XSL transformation.
if Employee/EmployeeInfo/FirstName = EmployeeSegment/EmployeeSummary/GivenName and Employee/EmployeeInfo/LastName = EmployeeSegment/EmployeeSummary/Surname
employeeId = EmployeeSegment/EmployeeSummary/EmpId
XML1
<Employee>
<EmployeeInfo>
<FirstName>ABC</FirstName>
<LastName>DEF</LastName>
</EmployeeInfo>
</Employee>
XML2
<EmployeeSegment>
<EmployeeSummary>
<EmpId>1234</EmpId>
<GivenName>ABC</GivenName>
<Surname>DEF</Surname>
</EmployeeSummary>
</EmployeeSegment>
I have tried the following. It is not working.
<xsl:param name="cjEmployeeSegment" select="document('CJ_Response.xml')"/>
<xsl:for-each select="/ns3:Employee/ns3:EmployeeInfo">
<xsl:variable name="empFirstName">
<xsl:value-of select="ns1:FirstName"/>
</xsl:variable>
<xsl:variable name="empLastName">
<xsl:value-of select="ns1:LastName"/>
</xsl:variable>
<xsl:for-each select="$cjEmployeeSegment/v32:EmployeeSegment/v31:EmployeeSummary">
<xsl:if test="$empFirstName=v31:GivenName and $empLastName=v31:Surname">
<ns12:EmployeeIdentifier>
<ns12:EmployeeID>
<xsl:value-of select="v31:EmpId"/>
</ns12:EmployeeID>
</ns12:EmployeeIdentifier>
</xsl:if>
</xsl:for-each>
</xsl:for-each>
Assuming you are processing the following input:
XML
<Employee>
<EmployeeInfo>
<FirstName>ABC</FirstName>
<LastName>DEF</LastName>
</EmployeeInfo>
</Employee>
and there is another XML document named CJ_Response.xml:
<EmployeeSegment>
<EmployeeSummary>
<EmpId>1234</EmpId>
<GivenName>ABC</GivenName>
<Surname>DEF</Surname>
</EmployeeSummary>
</EmployeeSegment>
you can use the following stylesheet:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:param name="cj_Response" select="document('CJ_Response.xml')"/>
<xsl:template match="/Employee">
<root>
<xsl:for-each select="EmployeeInfo">
<xsl:variable name="lookup" select="$cj_Response/EmployeeSegment/EmployeeSummary[GivenName = current()/FirstName and Surname = current()/LastName]" />
<xsl:if test="$lookup">
<EmployeeIdentifier>
<EmployeeID>
<xsl:value-of select="$lookup/EmpId"/>
</EmployeeID>
</EmployeeIdentifier>
</xsl:if>
</xsl:for-each>
</root>
</xsl:template>
</xsl:stylesheet>
to return:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<EmployeeIdentifier>
<EmployeeID>1234</EmployeeID>
</EmployeeIdentifier>
</root>
Of course, this will fail miserably if there are two or more employees with the same name.

How to Derive/Calculate Upper/Lower Corner in GML Envelope with XSL from PosList XML

Seeking advice on how to calculate the lowerCorner and upperCorner in GML Envelope given an array (coordinates) in the XML. Note I have reduced the list of coordinates significantly to keep short.
Aware I need to iterate the <coordinates> element but unsure most efficient way to calculate the lowerCorner and upperCorner pairs to eventually map into the GML Envelope.
XML Sample
<?xml version="1.0" encoding="UTF-8"?>
<Extract>
<n1:XMLExtract xmlns:n1="urn:com:aaa">
<regionId>4671</regionId>
<coordinates>151.344553 -33.4123250000193, 151.346606 -33.4126370000193, 151.347188 -33.4127280000193, 151.347707 -33.4127990000193, 151.347858 -33.4121160000193, 151.34931 -33.4123270000192, 151.349253 -33.4125910000192, 151.349693 -33.4126610000193, 151.34963 -33.4129810000192, 151.351338 -33.4132280000193, 151.351393 -33.4129550000193, 151.352038 -33.4130480000192, 151.352169 -33.4128100000193, 151.352355 -33.4128370000193, 151.35249 -33.4128910000193, 151.352585 -33.4129170000193, 151.352913 -33.4130080000193, 151.35294 -33.4131310000193, 151.355307 -33.4134860000192, 151.355315 -33.4134470000193, 151.355764 -33.4135020000193, 151.355757 -33.4135590000193, 151.356196 -33.4136240000192, 151.356229 -33.4134890000192, 151.356342 -33.4136260000193, 151.358407 -33.4139280000192, 151.358335 -33.4142510000192, 151.358465 -33.4143660000193, 151.359572 -33.4145260000194, 151.359936 -33.4144860000193, 151.360146 -33.4146080000193, 151.360627 -33.4146790000192, 151.360619 -33.4146980000193, 151.362603 -33.4149980000193, 151.362996 -33.4150940000193, 151.363655 -33.4158080000193, 151.364236 -33.4161380000194, 151.365691 -33.4163460000193, 151.366212 -33.4164920000193, 151.367333 -33.4170870000193, 151.368456 -33.4180250000193, 151.368481 -33.4180200000193, 151.368888 -33.4183130000193, 151.371305 -33.4187840000193, 151.373106 -33.4187890000193, 151.374004 -33.4189970000194, 151.374994 -33.4194460000193, 151.376513 -33.4199650000193, 151.378063 -33.4197680000193, 151.379519 -33.4185780000193, 151.383555 -33.4161210000193, 151.393929 -33.4059400000192, 151.396063 -33.4062720000193, 151.396727 -33.4051740000192, 151.39785 -33.4032380000193, 151.397122 -33.4027200000192, 151.396761 -33.4022700000193, 151.396541 -33.4008350000192, 151.397496 -33.3995910000192, 151.397788 -33.3990280000193, 151.397788 -33.3990100000192, 151.397773 -33.3990000000192, </coordinates>
<interactionId xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="1" />
<interactionTypeId xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="1" />
<refNumber/>
<incidentNumber/>
<payloadId>20002065</payloadId>
<filename/>
<url/>
</n1:XMLExtract>
</Extract>
Desired output as follows:
<gml:boundedBy>
<gml:Envelope srsDimension="2" srsName="EPSG:4283">
<gml:lowerCorner>-30.511985 151.63592</gml:lowerCorner>
<gml:upperCorner>-30.49207 151.669169</gml:upperCorner>
</gml:Envelope>
</gml:boundedBy>
Assuming you want to find the coordinates of the rectangle bounding your polygon, and assuming your processor supports the EXSLT extension functions str:split(), math:min() and math:max() (IOW, you are using either libxslt or Xalan), you could do something like:
XSLT 1.0 + EXSLT
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:n1="urn:com:aaa"
xmlns:exsl="http://exslt.org/common"
xmlns:math="http://exslt.org/math"
xmlns:str="http://exslt.org/strings"
extension-element-prefixes="exsl math str"
exclude-result-prefixes="n1">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/Extract">
<xsl:variable name="vertices-rtl">
<xsl:for-each select="str:split(n1:XMLExtract/coordinates, ', ')">
<v x="{substring-before(., ' ')}" y="{substring-after(., ' ')}"/>
</xsl:for-each>
</xsl:variable>
<xsl:variable name="vertices" select="exsl:node-set($vertices-rtl)/v" />
<output>
<lowerLeft>
<xsl:value-of select="math:min($vertices/#x)" />
<xsl:text> </xsl:text>
<xsl:value-of select="math:min($vertices/#y)" />
</lowerLeft>
<upperRight>
<xsl:value-of select="math:max($vertices/#x)" />
<xsl:text> </xsl:text>
<xsl:value-of select="math:max($vertices/#y)" />
</upperRight>
</output>
</xsl:template>
</xsl:stylesheet>
Applied to your example input, the result will be:
<?xml version="1.0" encoding="UTF-8"?>
<output>
<lowerLeft>151.344553 -33.4199650000193</lowerLeft>
<upperRight>151.39785 -33.3990000000192</upperRight>
</output>

XSL cross reference

I am stuck with a XSLT 1.0 problem. I tried to find info on StackOverflow but I couldn't apply the examples.
Here is the structure of my XML:
<XML>
<PR>
<AS>
<ID_AS>AS-001</ID_AS>
<FIRST>
<ID_CATALOG>Id-001</ID_CATALOG>
<STATUS>NOK</STATUS>
</FIRST>
<SECOND>
<ID_CATALOG>Id-002</ID_CATALOG>
<STATUS>OK</STATUS>
</SECOND>
</AS>
<AS>
<ID_AS>AS-002</ID_AS>
<FIRST>
<ID_CATALOG>Id-003</ID_CATALOG>
<STATUS>OK</STATUS>
</FIRST>
<SECOND>
<ID_CATALOG>Id-004</ID_CATALOG>
<STATUS>OK</STATUS>
</SECOND>
</AS>
</PR>
<METADATA>
<ID_CATALOG>Id-001</ID_CATALOG>
<ANGLES>32.25</ANGLES>
</METADATA>
<METADATA>
<ID_CATALOG>Id-002</ID_CATALOG>
<ANGLES>18.75</ANGLES>
</METADATA>
<METADATA>
<ID_CATALOG>Id-003</ID_CATALOG>
<ANGLES>5.23</ANGLES>
</METADATA>
<METADATA>
<ID_CATALOG>Id-004</ID_CATALOG>
<ANGLES>12.41</ANGLES>
</METADATA>
</XML>
I want to display for each AS, the FIRST/ID_CATALOG, FIRST/STATUS and ANGLES corresponding to the ID_CATALOG, then SECOND/etc.
The output would be similar to:
AS-001
Id-001 NOK 32.25
Id-002 OK 18.75
AS-002
Id-003 OK 5.23
Id-004 OK 12.41
I tried the following XSL but I only get the ANGLES for the first item
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns="http://earth.google.com/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:hma="http://earth.esa.int/hma" xmlns:gml="http://www.opengis.net/gml" xmlns:xlink="http://www.w3.org/1999/xlink">
<xsl:output method="xml" indent="yes" encoding="ISO-8859-1"/>
<!--==================MAIN==================-->
<xsl:template match="/">
<html>
<body>
AS List:
<br/><br/>
<xsl:call-template name="ASandCo"/>
</body>
</html>
</xsl:template>
<!--==================TEMPLATES==================-->
<xsl:template name="ASandCo">
<AS>
<xsl:for-each select="XML/PR/AS">
<xsl:value-of select="ID_AS"/>
<br/>
<xsl:value-of select="FIRST/ID_CATALOG"/> - <xsl:value-of select="FIRST/STATUS"/> -
<xsl:if test="contains(/XML/METADATA/ID_CATALOG, FIRST/ID_CATALOG)">
<xsl:value-of select="/XML/METADATA/ANGLES"/>
</xsl:if>
<br/>
<xsl:value-of select="SECOND/ID_CATALOG"/> - <xsl:value-of select="SECOND/STATUS"/> -
<xsl:if test="contains(/XML/METADATA/ID_CATALOG, SECOND/ID_CATALOG)">
<xsl:value-of select="/XML/METADATA/ANGLES"/>
</xsl:if>
<br/><br/>
</xsl:for-each>
</AS>
</xsl:template>
</xsl:stylesheet>
This XSLT will be applied to very large XML files, so I am trying to find the most efficient way.
Thank you very much in advance!
It seems like you want to look up some metadata metadata based on the ID_CATALOG value.
An efficient way to do this is by using a key. You can define a key on the top level:
<xsl:key name="metadata-by-id_catalog" match="METADATA" use="ID_CATALOG"/>
And then you can look up the ANGLES value using the key for a given ID_CATALOG value like this:
<xsl:value-of select="key('metadata-by-id_catalog', FIRST/ID_CATALOG)/ANGLES"/>
and this:
<xsl:value-of select="key('metadata-by-id_catalog', SECOND/ID_CATALOG)/ANGLES"/>

XSLT transform error

I have the following xml:
<RootNode xmlns="http://someurl/path/path/path">
<Child1>
<GrandChild1>Value</GrandChild1>
<!-- Lots more elements in here-->
</Child1>
</RootNode>
I have the following xslt:
<xsl:stylesheet version="1.0" xmlns="http://someurl/path/path/path" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:output method="xml" encoding="UTF-8" indent="yes"/>
<xsl:template match="/">
<NewRootNode xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<NewChild1>
<xsl:for-each select="RootNode/Child1">
<NewNodeNameHere>
<xsl:value-of select="GrandChild1"/>
</NewNodeNameHere>
<!-- lots of value-of tags in here -->
</xsl:for-each>
</NewChild1>
</NewRootNode >
</xsl:template>
</xsl:stylesheet>
The problem: this is the my result:
<?xml version="1.0" encoding="utf-8"?>
<NewRootNode xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<NewChild1 />
</NewRootNode>
I am expecting to see:
<?xml version="1.0" encoding="utf-8"?>
<NewRootNode xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<NewChild1>
<NewNodeNameHere>Value</NewNodeNameHere>
<!-- Other new elements with values from the xml file -->
</NewChild1>
</NewRootNode>
I am missing of the information inside of NewChild1 that should be there.
I think my for-each select is correct, so the only thing I can think of is that there is a problem with the namespace in the Xml and the namespace in the xslt. Can anybody see what I'm doing wrong?
The problem is caused by the namespaces.
Since the xml defines xmlns="http://someurl/path/path/path", it is not in the default namespace anymore.
You can define that namespace with an name like xmlns:ns="http://someurl/path/path/path" in the xsl, and then use that name in the XPath expression.
The following works for me:
<xsl:stylesheet version="1.0" xmlns:ns="http://someurl/path/path/path" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:output method="xml" encoding="UTF-8" indent="yes"/>
<xsl:template match="/">
<NewRootNode xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<NewChild1>
<xsl:for-each select="ns:RootNode/ns:Child1">
<NewNodeNameHere>
<xsl:value-of select="ns:GrandChild1"/>
</NewNodeNameHere>
<!-- lots of value-of tags in here -->
</xsl:for-each>
</NewChild1>
</NewRootNode >
</xsl:template>
</xsl:stylesheet>
The stylesheet namespace should be http://www.w3.org/1999/XSL/Transform instead of http://someurl/path/path/path.
Also, since the input XML uses a namespace all your XPath expressions should be namespace-qualified:
<xsl:template match="/" xmlns:ns1="http://someurl/path/path/path">
<NewRootNode xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<NewChild1>
<xsl:for-each select="ns1:RootNode/ns1:Child1">
<NewNodeNameHere>
<xsl:value-of select="ns1:GrandChild1"/>
</NewNodeNameHere>
<!-- lots of value-of tags in here -->
</xsl:for-each>
</NewChild1>
</NewRootNode>
</xsl:template>

attribute value using msxml from xml

I have the following XML
<?xml version="1.0" encoding="ISO-8859-1" ?>
- <DEVICEMESSAGES>
<VERSION xml="1" checksum="" revision="0" envision="33050000" device="" />
<HEADER id1="0001" id2="0001" content="Nasher[<messageid>]: <!payload>" />
<MESSAGE level="7" parse="1" parsedefvalue="1" tableid="15" id1="24682" id2="24682" eventcategory="1003010000" content="Access to <webpage> was blocked due to its category (<info> by <hostname>)" />
</DEVICEMESSAGES>
I am using the following xslt
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<xsl:template match="DEVICEMESSAGES">
<xsl:value-of select="#id2"/>,<xsl:text/>
<xsl:value-of select="#content"/>,<xsl:text/>
<xsl:text>
</xsl:text>
</xsl:template>
</xsl:stylesheet>
when i use MSXML i just get ,, whereas i want to have something like
id2, content
0001 , Nasher[<messageid>]: <!payload>"
The DEVICEMESSAGES element doesn't have attributes at all.
Change:
<xsl:template match="DEVICEMESSAGES">
to:
<xsl:template match="DEVICEMESSAGES/HEADER">