I'm using XSLT to generate a report with a date column. In the spreadsheet XLSX file, if I pass through the date as a string, when opening it with a spreadsheet package such as Excel, it will assume it's a date (which is correct) but then format it as MM/dd/yyyy when what we actually want is dd/MM/yyyy. This appears to be the spreadsheet package that is causing this, however I was wondering if you could define cell formatting from the XSLT?
Here is the code I'm using to do this:
<xsl:template match="SomeTemplate">
<Row>
...
<Cell>
<xsl:value-of select="ms:format-date(StartTime, 'dd/MM/yyyy')" />
<xsl:text> </xsl:text>
<xsl:value-of select="ms:format-time(StartTime, 'HH:mm:ss')" />
</Cell>
...
</Row>
</xsl:template>
I've attempted other ways around this such as starting the cell with ' but strangely this didn't work!
Here's an XML sample relevant to the XSLT above:
...
<Destination>
<StartTime>2013-03-07T00:01:09</StartTime>
<EndTime>2013-03-07T10:41:09</EndTime>
...
</Destination>
...
The cell formatting in Excel xml can be done via styles.
I.e you fill the cells with dates in xs:datetime format (you do not need any ms:format-date conversion at all in your example) but specify the cell style though ss:styleId:
<Destination>
<StartTime>2013-03-07T00:01:09</StartTime>
<EndTime>2013-03-07T10:41:09</EndTime>
</Destination>
+
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ms="urn:schemas-microsoft-com:xslt"
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
xmlns="urn:schemas-microsoft-com:office:spreadsheet"
version="1.0">
<xsl:template match="/">
<Workbook>
<Styles>
<Style ss:ID="style_default">
<NumberFormat ss:Format="Short Date"/>
</Style>
<Style ss:ID="style_ddslashmmslashyy">
<NumberFormat ss:Format="dd/mm/yy;#"/>
</Style>
</Styles>
<Worksheet ss:Name="Sheet1">
<Table>
<xsl:apply-templates/>
</Table>
</Worksheet>
</Workbook>
</xsl:template>
<xsl:template match="Destination">
<Row>
<Cell ss:StyleID="style_default">
<Data ss:Type="DateTime"><xsl:value-of select="StartTime"/></Data>
</Cell>
<Cell ss:StyleID="style_ddslashmmslashyy">
<Data ss:Type="DateTime"><xsl:value-of select="StartTime"/></Data>
</Cell>
</Row>
</xsl:template>
</xsl:stylesheet>
Related
I have an old XSLT stylesheet that still works, but only transforms to Excel xls files. I've used ClosedXml to convert grid data to Excel xlsx files and it works great, but I have some formatted Excel documents that are not grids and require some formatting and layout. I would like to convert those old XSLT stylesheets to create the new(er) XLSX format files but only replacing
xmlns="urn:schemas-microsoft-com:office:spreadsheet"
with
xmlns="http://schemas.openxmlformats.org/officeDocument/2006/
doesn't work.
Has anyone updated an XSLT stylesheet to produce output to Excel xlsx? If yes, please share what you needed to do to accomplish it.
Here's the XSLT stylesheet that I'm trying to convert:
<xsl:stylesheet version="1.0" xmlns="urn:schemas-microsoft-com:office:spreadsheet" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:user="urn:my-scripts" xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet">
<xsl:template match="/">
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet" xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:html="http://www.w3.org/TR/REC-html40">
<Styles>
.. styles
</Styles>
<Worksheet ss:Name="name">
<Table ss:ExpandedColumnCount="9" x:FullColumns="1" x:FullRows="1" ss:DefaultRowHeight="13.2">
<Column ss:Index="2" ss:Width="77"/>
<Column ss:Index="5" ss:Width="54"/>
<Column ss:Index="8" ss:Width="178"/>
<xsl:for-each select="ReportRows/ReportRow">
<xsl:if test="position()=1">
<Row>
<Cell ss:MergeAcross="8" ss:StyleID="s30">
<Data ss:Type="String">
<xsl:value-of select="SE_Year" /> Title #Lab
</Data>
</Cell>
</Row>
</xsl:if>
<xsl:if test="Pr_Short_Name != Prev_Project">
<Row>
<Cell ss:MergeAcross="8" ss:StyleID="s24" />
</Row>
<Row>
<Cell ss:MergeAcross="8" ss:StyleID="s27">
<Data ss:Type="String">
<xsl:value-of select="Pr_Long_Name" />
</Data>
</Cell>
</Row>
<Row ss:AutoFitHeight="0">
cells...
</Row>
</xsl:if>
<xsl:if test="GR_Short_Name != Prev_SampleTypeGroup">
<Row>
<Cell ss:MergeAcross="8" ss:StyleID="s31" />
</Row>
<Row>
<Cell ss:MergeAcross="8" ss:StyleID="s32">
<Data ss:Type="String">
<xsl:value-of select="GR_Short_Name" />
</Data>
</Cell>
</Row>
</xsl:if>
<Row ss:Height="41.4">
cells...
</Row>
</xsl:for-each>
<Row ss:Height="13.8">
<Cell ss:MergeAcross="8" ss:MergeDown="1" ss:StyleID="m15419890" />
</Row>
</Table>
<WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel">
<PageSetup>
<Header x:Margin="0" />
<Footer x:Margin="0.3" x:Data="&L&8Form Print Date/Time: &D &T&C&8Page &P of &N" />
<PageMargins x:Bottom="0.95" x:Left="0.5" x:Right="0.5" x:Top="0.5" />
</PageSetup>
<Print>
<ValidPrinterInfo />
<Scale>100</Scale>
<HorizontalResolution>600</HorizontalResolution>
<VerticalResolution>600</VerticalResolution>
</Print>
<Selected />
<DoNotDisplayGridlines />
<Panes>
<Pane>
<Number>3</Number>
<ActiveRow>8</ActiveRow>
<ActiveCol>10</ActiveCol>
</Pane>
</Panes>
<ProtectObjects>False</ProtectObjects>
<ProtectScenarios>False</ProtectScenarios>
</WorksheetOptions>
</Worksheet>
</Workbook>
</xsl:template>
</xsl:stylesheet>
I have input like:
<item id="CON_1985_14">
<prv id="p1">
<no>1</no>
<text>This "May" take some moment, you "shall" not go there.</text>
<text>This is ok.</text>
</prv>
</item>
Need to create a excel table on the basis of quoted values.
=========================
A B
=========================
May CON_1985_14
shall CON_1985_14
=========================
Created XSLT to generate excel output like:
<Worksheet ss:Name="R6">
<Table>
<Row>
<Cell>
<Data ss:Type="String">
<xsl:text>A</xsl:text>
</Data>
</Cell>
<Cell>
<Data ss:Type="String">
<xsl:text>B</xsl:text>
</Data>
</Cell>
</Row>
<xsl:for-each select="$path">
<xsl:for-each select="descendant::prv//descendant::text">
<xsl:variable name="STRUCTUREONBASISOFTOKENS" as="node()">
<Report>
<dd>
<xsl:for-each select="tokenize(normalize-space(.), '("|“)')">
<xsl:if test="(position() gt 1) and (position() mod 2 = 0)">
<xsl:value-of select="normalize-space(.)"/>
<xsl:if test="position() ne (last() - 1)">
<xsl:text>, </xsl:text>
</xsl:if>
</xsl:if>
</xsl:for-each>
</dd>
<LID>
<xsl:value-of select="/item/#id"/>
</LID>
</Report>
</xsl:variable>
<xsl:for-each select="tokenize($STRUCTUREONBASISOFTOKENS/Report/dd, ',')">
<Row>
<Cell>
<Data ss:Type="String">
<xsl:value-of select="normalize-space(.)"/>
</Data>
</Cell>
<Cell>
<Data ss:Type="String">
<xsl:value-of select="$STRUCTUREONBASISOFTOKENS/Report/LID"/>
</Data>
</Cell>
</Row>
</xsl:for-each>
</xsl:for-each>
</xsl:for-each>
</Table>
</Worksheet>
The variable created inside for-each having output printed in message like:
<Report xmlns:html="http://www.w3.org/TR/REC-html40" xmlns:LxNx="http://www.LXNX.com"
xmlns="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:dict="http://www.lexis-nexis.com/glp/dict" xmlns:ci="http://www.lexis-nexis.com/ci"
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:x="urn:schemas-microsoft-com:office:excel"
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet">
<dd>May, shall</dd>
<LID>CON_1985_14</LID>
</Report>
Now the nested for-each, just below the variable define is trying to fetch the values from the variable structure to generate the ROWs, but not succeed..
Not able to fetch the values from the variable by xpath to generate row.
This syntax '' means the collection() path.
Provide the suitable solution for that.
I could not follow the logic of your attempted XSLT. Consider the following simplified example:
XML
<input>
<item>Lorem ipsum "alpha" dolor sit amet, consectetur "bravo" adipiscing elit "charlie".</item>
<item>"Delta" sed do eiusmod tempor "echo" incididunt ut labore et dolore magna aliqua.</item>
</input>
XSLT 2.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="/input">
<table>
<xsl:for-each select="item">
<xsl:analyze-string select="." regex=""(.*?)"">
<xsl:matching-substring>
<row>
<cell>
<xsl:value-of select="regex-group(1)" />
</cell>
</row>
</xsl:matching-substring>
</xsl:analyze-string>
</xsl:for-each>
</table>
</xsl:template>
</xsl:stylesheet>
Result
<?xml version="1.0" encoding="UTF-8"?>
<table>
<row>
<cell>alpha</cell>
</row>
<row>
<cell>bravo</cell>
</row>
<row>
<cell>charlie</cell>
</row>
<row>
<cell>Delta</cell>
</row>
<row>
<cell>echo</cell>
</row>
</table>
Demo: https://xsltfiddle.liberty-development.net/6rewNy4
I have this structure
<ROWS>
<ROW>
<TEXT> This is a #good# #day# </TEXT>
<good>great</good>
<day>month</day>
</ROW>
<ROW>
<TEXT> This is a #good# #day# </TEXT>
<good>Fun</good>
<day>morning</day>
</ROW>
</ROWS>
How do I change that to
<statement> This is a great month, this is a Fun morning </statement>
Using only XSLT 1.0?
The original XML can change tag name. But not the structure! Any ideas?
This seems somewhat similar to creating form letters from a template. Assuming the example is not to be meant literally, you could try something like:
<?xml version="1.0" encoding="UTF-8"?>
<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:template match="/">
<statements>
<xsl:for-each select="ROWS/ROW/TEXT">
<statement>
<xsl:call-template name="merge">
<xsl:with-param name="string" select="."/>
</xsl:call-template>
</statement>
</xsl:for-each>
</statements>
</xsl:template>
<xsl:template name="merge">
<xsl:param name="string"/>
<xsl:param name="sep" select="'#'"/>
<xsl:choose>
<xsl:when test="contains($string, $sep) and contains(substring-after($string, $sep), $sep)">
<xsl:value-of select="substring-before($string, $sep)" />
<xsl:variable name="placeholder" select="substring-before(substring-after($string, $sep), $sep)" />
<xsl:value-of select="../*[name() = $placeholder]" />
<!-- recursive call -->
<xsl:call-template name="merge">
<xsl:with-param name="string" select="substring-after(substring-after($string, $sep), $sep)" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$string" />
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
Given an input of:
<ROWS>
<ROW>
<TEXT>The quick brown #animal# jumps over the #property# dog.</TEXT>
<animal>fox</animal>
<property>lazy</property>
</ROW>
<ROW>
<TEXT>A journey of a #number# miles #action# with a single #act#.</TEXT>
<number>thousand</number>
<action>begins</action>
<act>step</act>
</ROW>
</ROWS>
the result will be:
<?xml version="1.0" encoding="UTF-8"?>
<statements>
<statement>The quick brown fox jumps over the lazy dog.</statement>
<statement>A journey of a thousand miles begins with a single step.</statement>
</statements>
Look at the XSLT 1.0 spec; find the section on string functions. Study the contains, substring-before, and substring-after functions. The solution to your problem should become clear; if it doesn't, you should at least be able to get far enough on your problem to pose a question that does not look as if it could be paraphrased as "Please do my homework for me."
I have some code that loads in an xml file and applies an XSLT to it using “XslCompiledTransform”. I now need to change the code as the input file may not be XML, it could also be a CSV file. I have an XSLT that will convert the CSV to the format I want but it uses a hardcoded path. The problem I have is that the input filename will change so can I use a widecard in the name? Secondly, in code can I pass in the file as a string to an XSLT object and have the result fall out the bottom? I’ve been doing some googling and not found any code to do this. Is it even possible?
Here is the XSLT I am using. Not the hardcoded path and filename.
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:fn="fn"
exclude-result-prefixes="xs fn">
<xsl:output indent="yes" encoding="US-ASCII"/>
<xsl:param name="pathToCSV" select="'file:///C:/Downloads/inputcsv.csv'"/>
<xsl:function name="fn:getTokens" as="xs:string+">
<xsl:param name="str" as="xs:string"/>
<xsl:analyze-string select="concat($str, ',')" regex='(("[^"]*")+|[^,]*),'>
<xsl:matching-substring>
<xsl:sequence select='replace(regex-group(1), "^""|""$|("")""", "$1")'/>
</xsl:matching-substring>
</xsl:analyze-string>
</xsl:function>
<xsl:template match="/" name="main">
<xsl:choose>
<xsl:when test="unparsed-text-available($pathToCSV)">
<xsl:variable name="csv" select="unparsed-text($pathToCSV)"/>
<xsl:variable name="lines" select="tokenize($csv, '
')" as="xs:string+"/>
<xsl:variable name="elemNames" select="fn:getTokens($lines[1])" as="xs:string+"/>
<root>
<xsl:for-each select="$lines[position() > 0]">
<row>
<xsl:variable name="lineItems" select="fn:getTokens(.)" as="xs:string+"/>
<xsl:for-each select="$elemNames">
<xsl:variable name="pos" select="position()"/>
<column>
<xsl:value-of select="$lineItems[$pos]"/>
</column>
</xsl:for-each>
</row>
</xsl:for-each>
</root>
</xsl:when>
<xsl:otherwise>
<xsl:text>Cannot locate : </xsl:text><xsl:value-of select="$pathToCSV"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
Well XslCompiledTransform is an XSLT 1.0 processor so using XSLT 2.0 features like unparsed-text is not possible with XslCompiledTransform, you need to use Saxon 9 or XmlPrime or AltovaXML for XSLT 2.0.
Then you can pass in a parameter to your posted stylesheet as it has a global xsl:param named pathToCSV, how you pass in that parameter depends on the API of the XSLT processor you want to use (or on its command line parameters if you simply want to execute the stylesheet from the command line).
New guy here so bear with me. Ive got a basic XSL file that will read my xml data. Im trying to put xml into Excel. Heres my issue. With a small XML file it seems to convert it easly, BUT with this XML file that had several nodes ( I think they are called), when I call up the data, its not right. I want to only show info from the check portion of XML and then show it in Excel in a way that shows the 6 or 7 columns that I want, then show the data. Heres what I have so far:
XML:
<bdiData>
<documentControlInfo>
<documentInfo>
<docDescription>Checks for Company X</docDescription>
<docID>
<ID>123456789</ID>
</docID>
<docModifier>My Company</docModifier>
<docCreateDate>2010-08-23</docCreateDate>
<docCreateTime>07:08:54-0700</docCreateTime>
<standardVersion>1.0</standardVersion>
<testIndicator>0</testIndicator>
<resendIndicator>0</resendIndicator>
</documentInfo>
<sourceInfo>
<sourceName>My Banking Name</sourceName>
<sourceID>
<idOther>ShortBankName</idOther>
</sourceID>
</sourceInfo>
<destinationInfo>
<destinationName>My Company</destinationName>
<destinationID>
<idOther>MYCO</idOther>
</destinationID>
</destinationInfo>
</documentControlInfo>
<checkItemCollection>
<collectionInfo>
<description>Items</description>
<ID>654811650</ID>
<Classification>
<classification>Items</classification>
</Classification>
</collectionInfo>
<checkItemBatch>
<checkItemBatchInfo>
<description>Paid Checks</description>
<ID>1239668334710</ID>
<Classification>
<classification>Paid Checks</classification>
</Classification>
</checkItemBatchInfo>
<checkItem>
<checkItemType>check</checkItemType>
<checkAmount>2960</checkAmount>
<postingInfo>
<date>2009-06-12</date>
<RT>87654321</RT>
<accountNumber>123465798</accountNumber>
<seqNum>007725552898</seqNum>
<trancode>001152</trancode>
<amount>2960</amount>
<serialNumber>55225410</serialNumber>
</postingInfo>
XSL File:
<xsl:stylesheet version="1.0"
xmlns="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:user="urn:my-scripts"
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:x="urn:schemas-microsoft-com:office:excel"
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" >
<xsl:template match="/">
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:x="urn:schemas-microsoft-com:office:excel"
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:html="http://www.w3.org/TR/REC-html40">
<xsl:apply-templates/>
</Workbook>
</xsl:template>
<xsl:template match="/*">
<Worksheet>
<xsl:attribute name="ss:Name">
<xsl:value-of select="local-name(/*/*)"/>
</xsl:attribute>
<Table x:FullColumns="1" x:FullRows="1">
<Row>
<xsl:for-each select="*[position() = 2]/*/checkItem/postingInfo/*">
<Cell>
<Data ss:Type="String">
<xsl:value-of select="local-name()"/>
</Data>
</Cell>
</xsl:for-each>
</Row>
<xsl:apply-templates/>
</Table>
</Worksheet>
</xsl:template>
<xsl:template match="/*/checkItem/postingInfo/*">
<Row>
<xsl:apply-templates/>
</Row>
</xsl:template>
<xsl:template match="/*/checkItem/postingInfo/*">
<Cell>
<Data ss:Type="String">
<xsl:value-of select="."/>
</Data>
</Cell>
</xsl:template>
</xsl:stylesheet>
Does anyone have any Idea how I can get to JUSt the check portion f the XML file and have it format in an eay way??
Thanks
GabrielVA
I think you need this stylesheet:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
xmlns:x="urn:schemas-microsoft-com:office:excel">
<xsl:template match="/">
<xsl:processing-instruction name="mso-application">progid="Excel.Sheet"</xsl:processing-instruction>
<Workbook>
<xsl:apply-templates/>
</Workbook>
</xsl:template>
<xsl:template match="/*">
<Worksheet ss:Name="{*/*/*[local-name()='docDescription']}">
<Table x:FullColumns="1" x:FullRows="1">
<Row>
<xsl:for-each select="*/*/*[local-name()='checkItem'][1]//*[not(*)]">
<Cell>
<Data ss:Type="String">
<xsl:value-of select="local-name()"/>
</Data>
</Cell>
</xsl:for-each>
</Row>
<xsl:apply-templates select="*/*/*[local-name()='checkItem']"/>
</Table>
</Worksheet>
</xsl:template>
<xsl:template match="*[local-name()='checkItem']" priority="1">
<Row>
<xsl:apply-templates select=".//*[not(*)]"/>
</Row>
</xsl:template>
<xsl:template match="*[not(*)]">
<Cell>
<Data ss:Type="String">
<xsl:value-of select="."/>
</Data>
</Cell>
</xsl:template>
</xsl:stylesheet>
With this input (proper well formed):
<bdiData>
<documentControlInfo>
<documentInfo>
<docDescription>Checks for Company X</docDescription>
<docID>
<ID>123456789</ID>
</docID>
<docModifier>My Company</docModifier>
<docCreateDate>2010-08-23</docCreateDate>
<docCreateTime>07:08:54-0700</docCreateTime>
<standardVersion>1.0</standardVersion>
<testIndicator>0</testIndicator>
<resendIndicator>0</resendIndicator>
</documentInfo>
<sourceInfo>
<sourceName>My Banking Name</sourceName>
<sourceID>
<idOther>ShortBankName</idOther>
</sourceID>
</sourceInfo>
<destinationInfo>
<destinationName>My Company</destinationName>
<destinationID>
<idOther>MYCO</idOther>
</destinationID>
</destinationInfo>
</documentControlInfo>
<checkItemCollection>
<collectionInfo>
<description>Items</description>
<ID>654811650</ID>
<Classification>
<classification>Items</classification>
</Classification>
</collectionInfo>
<checkItemBatch>
<checkItemBatchInfo>
<description>Paid Checks</description>
<ID>1239668334710</ID>
<Classification>
<classification>Paid Checks</classification>
</Classification>
</checkItemBatchInfo>
<checkItem>
<checkItemType>check</checkItemType>
<checkAmount>2960</checkAmount>
<postingInfo>
<date>2009-06-12</date>
<RT>87654321</RT>
<accountNumber>123465798</accountNumber>
<seqNum>007725552898</seqNum>
<trancode>001152</trancode>
<amount>2960</amount>
<serialNumber>55225410</serialNumber>
</postingInfo>
</checkItem>
</checkItemBatch>
</checkItemCollection>
</bdiData>
Output:
<?mso-application progid="Excel.Sheet"?>
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet" xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" xmlns:x="urn:schemas-microsoft-com:office:excel">
<Worksheet ss:Name="Checks for Company X">
<Table x:FullColumns="1" x:FullRows="1">
<Row>
<Cell>
<Data ss:Type="String">checkItemType</Data>
</Cell>
<Cell>
<Data ss:Type="String">checkAmount</Data>
</Cell>
<Cell>
<Data ss:Type="String">date</Data>
</Cell>
<Cell>
<Data ss:Type="String">RT</Data>
</Cell>
<Cell>
<Data ss:Type="String">accountNumber</Data>
</Cell>
<Cell>
<Data ss:Type="String">seqNum</Data>
</Cell>
<Cell>
<Data ss:Type="String">trancode</Data>
</Cell>
<Cell>
<Data ss:Type="String">amount</Data>
</Cell>
<Cell>
<Data ss:Type="String">serialNumber</Data>
</Cell>
</Row>
<Row>
<Cell>
<Data ss:Type="String">check</Data>
</Cell>
<Cell>
<Data ss:Type="String">2960</Data>
</Cell>
<Cell>
<Data ss:Type="String">2009-06-12</Data>
</Cell>
<Cell>
<Data ss:Type="String">87654321</Data>
</Cell>
<Cell>
<Data ss:Type="String">123465798</Data>
</Cell>
<Cell>
<Data ss:Type="String">007725552898</Data>
</Cell>
<Cell>
<Data ss:Type="String">001152</Data>
</Cell>
<Cell>
<Data ss:Type="String">2960</Data>
</Cell>
<Cell>
<Data ss:Type="String">55225410</Data>
</Cell>
</Row>
</Table>
</Worksheet>
</Workbook>
Wich is properly open by Excel.
Note: those fn:local-name() are there because your input sample is unreliable.