2011-03-11 85 views
0

我們可以分析這個XSL文件精細本次測試的XML文件:如何使用此XSLT文件解析此Excel XML導出文件?

測試XML:

<?xml version="1.0" encoding="UTF-8"?> 
<?xml-stylesheet href="newrows.xsl" type="text/xsl"?> 
<Workbook> 
    <Worksheet> 
     <Table> 
      <Row> 
       <Cell></Cell> 
       <Cell>(info...)</Cell> 
       <Cell></Cell> 
      </Row> 
      <Row> 
       <Cell>first name</Cell> 
       <Cell>last name</Cell> 
       <Cell>age</Cell> 
      </Row> 
      <Row> 
       <Cell>Jim</Cell> 
       <Cell>Smith</Cell> 
       <Cell>34</Cell> 
      </Row> 
      <Row> 
       <Cell>Roy</Cell> 
       <Cell>Rogers</Cell> 
       <Cell>22</Cell> 
      </Row> 
      <Row> 
       <Cell>(info...)</Cell> 
       <Cell></Cell> 
       <Cell>(info...)</Cell> 
      </Row> 

      <Row> 
       <Cell>Sally</Cell> 
       <Cell>Cloud</Cell> 
       <Cell>26</Cell> 
      </Row> 

      <Row> 
       <Cell>John</Cell> 
       <Cell>Randall</Cell> 
       <Cell>44</Cell> 
      </Row> 

     </Table> 
    </Worksheet> 
</Workbook> 

XSL:

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

    <xsl:output method="xml" indent="yes"/> 

    <xsl:param name="range-1-begin" select="1"/> 
    <xsl:param name="range-1-end" select="3"/> 

    <xsl:param name="range-2-begin" select="5"/> 
    <xsl:param name="range-2-end" select="6"/> 

    <xsl:template match="Table"> 
     <test> 
      <xsl:for-each select="Row"> 
       <xsl:if test="(position() &gt;= $range-1-begin and position() &lt;= $range-1-end) 
        or (position() &gt;= $range-2-begin and position() &lt;= $range-2-end)"> 
        <Row> 
         <xsl:for-each select="Cell"> 
          <xsl:if test="position() = 1 or position() = 3"> 
           <Cell> 
            <xsl:value-of select="."/> 
           </Cell> 
          </xsl:if> 
         </xsl:for-each> 
        </Row> 
       </xsl:if> 
      </xsl:for-each> 
     </test> 
    </xsl:template> 

</xsl:stylesheet> 

然而,當我們試圖解析此類似XML文件從Excel導出,它導出每個字段的內容,沒有XML元素標籤。我們甚至可以輸入kksljflskdjf而不是Table,並輸出每個XML元素的內容。

我必須在XML/XSL文件中進行更改,以便XSL文件正確解析XML?

Excel的XML(exceprts):

<?xml version="1.0"?> 
<?xml-stylesheet href="blackbox.xsl" type="text/xsl"?> 
<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"> 
    <DocumentProperties xmlns="urn:schemas-microsoft-com:office:office"> 
     <Author>MM</Author> 
     <LastAuthor>xx</LastAuthor> 
     ... 
<Worksheet ss:Name="OFFSET Individual"> 
     <Names> 
      <NamedRange ss:Name="_FilterDatabase" ss:RefersTo="='OFFSET Individual'!R3C2:R3C12" ss:Hidden="1"/> 
      <NamedRange ss:Name="Print_Area" ss:RefersTo="='OFFSET Individual'!R4C2:R435C15"/> 
      <NamedRange ss:Name="Muster" ss:RefersTo="='OFFSET Individual'!C1:C9"/> 
      <NamedRange ss:Name="PAP" ss:RefersTo="='OFFSET Individual'!C2"/> 
     </Names> 
     <Table ss:ExpandedColumnCount="31" ss:ExpandedRowCount="443" x:FullColumns="1" x:FullRows="1" ss:StyleID="s90" ss:DefaultColumnWidth="59" ss:DefaultRowHeight="15"> 
      <Column ss:StyleID="s416" ss:Hidden="1" ss:AutoFitWidth="0" ss:Width="61"/> 
      <Column ss:StyleID="s91" ss:AutoFitWidth="0" ss:Width="287"/> 
      <Column ss:StyleID="s547" ss:AutoFitWidth="0" ss:Width="216"/> 
      <Column ss:StyleID="s91" ss:AutoFitWidth="0" ss:Width="87"/> 
      <Column ss:StyleID="s92" ss:AutoFitWidth="0" ss:Width="202"/> 
      <Column ss:StyleID="s90" ss:AutoFitWidth="0" ss:Width="87"/> 
      <Column ss:StyleID="s101" ss:AutoFitWidth="0" ss:Width="284"/> 
      <Column ss:StyleID="s132" ss:Hidden="1" ss:AutoFitWidth="0" ss:Width="52"/> 
      <Column ss:StyleID="s137" ss:Hidden="1" ss:AutoFitWidth="0" ss:Width="47"/> 
      <Column ss:StyleID="s90" ss:Hidden="1" ss:AutoFitWidth="0" ss:Width="42"/> 
      <Column ss:StyleID="s90" ss:Hidden="1" ss:AutoFitWidth="0" ss:Width="39"/> 
      <Column ss:StyleID="s90" ss:Hidden="1" ss:AutoFitWidth="0" ss:Width="37"/> 
      <Column ss:StyleID="s113" ss:AutoFitWidth="0" ss:Width="47"/> 
      <Column ss:StyleID="s87" ss:Hidden="1" ss:AutoFitWidth="0" ss:Width="275"/> 
      <Column ss:StyleID="s458" ss:AutoFitWidth="0" ss:Width="89"/> 
      <Column ss:StyleID="s179" ss:AutoFitWidth="0" ss:Span="1"/> 
      <Column ss:Index="18" ss:StyleID="s168" ss:Hidden="1" ss:AutoFitWidth="0"/> 
      <Column ss:StyleID="s90" ss:Hidden="1" ss:AutoFitWidth="0"/> 
      <Column ss:StyleID="s377" ss:AutoFitWidth="0" ss:Width="202" ss:Span="2"/> 
      <Column ss:Index="23" ss:StyleID="s377" ss:AutoFitWidth="0" ss:Width="203"/> 
      <Row ss:AutoFitHeight="0" ss:Height="23"> 
       <Cell ss:Index="2" ss:StyleID="s142"> 
        <Data ss:Type="String">Paper Overview</Data> 
        <NamedCell ss:Name="PAP"/> 
        <NamedCell ss:Name="Muster"/> 
       </Cell> 
      </Row> 
      <Row ss:AutoFitHeight="0"> 
       <Cell ss:Index="2" ss:StyleID="s141"> 
        <Data ss:Type="String">Stand: 10.03.2011; 13:00 Uhr</Data> 
        <NamedCell ss:Name="PAP"/> 
        <NamedCell ss:Name="Muster"/> 
       </Cell> 
      </Row> 
         ... 

這裏是所產生的 「XML」 文件的一個例子:

enter image description here

補遺

這是完整的解決方案,其現在有用,謝謝@Dimitre!

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns="urn:schemas-microsoft-com:office:spreadsheet" 
    xmlns:y="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" 
    exclude-result-prefixes="y o x ss html" 
> 

<xsl:strip-space elements="*"/> 
    <xsl:output method="xml" indent="yes"/> 

    <xsl:param name="range-1-begin" select="1"/> 
    <xsl:param name="range-1-end" select="3"/> 

    <xsl:param name="range-2-begin" select="5"/> 
    <xsl:param name="range-2-end" select="6"/> 

    <xsl:template match="text()"/> 

    <xsl:template match="y:Table"> 
     <test> 
      <xsl:for-each select="y:Row"> 
       <xsl:if test="(position() &gt;= $range-1-begin and position() &lt;= $range-1-end) 
        or (position() &gt;= $range-2-begin and position() &lt;= $range-2-end)"> 
        <Row> 
         <xsl:for-each select="y:Cell"> 
          <xsl:if test="position() = 1 or position() = 3"> 
           <Cell> 
            <xsl:value-of select="."/> 
           </Cell> 
          </xsl:if> 
         </xsl:for-each> 
        </Row> 
       </xsl:if> 
      </xsl:for-each> 
     </test> 
    </xsl:template> 

</xsl:stylesheet> 
+0

一個[XSLT使用具有默認命名空間設置爲XMLNS XML源(HTTP的許多更多鈔票複製的://計算器。 com/questions/1344158/xslt-with-xml-source-that-has-a-default-namespace-set-to-xmlns) – 2011-03-11 13:45:39

回答

4

我有什麼在 XML/XSL文件來改變以便XSL文件 正確解析XML?

首先,您的術語是相當不正確的。將XSLT轉換應用於已解析的XML文檔。解析(通過XML解析器)是能夠應用轉換的先決條件。

這是XML,XPath和XSLT中最常見問題:

原因不能夠按名稱選擇第二份文件是因爲在它定義的默認namesace任何元素(xmlns="urn:schemas-microsoft-com:office:spreadsheet" )。

在XPath中,任何沒有前綴的名稱都被認爲是在「no namespace」中。因此,模板匹配Table<xsl:for-each>選擇元素將不匹配/選擇任何元素,因爲在XML文檔中不存在「沒有名稱空間」中的此類元素。

最可讀的解決方案是在XSLT樣式表中定義相同的名稱空間,並在任何XPath表達式/匹配模式中使用前綴名稱。

因此,在修正的XSLT樣式表,你將有

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:y="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" 
    exclude-result-prefixes="y o x ss html" 
> 
    <xsl:output method="xml" indent="yes"/> 

    <xsl:param name="range-1-begin" select="1"/> 
    <xsl:param name="range-1-end" select="3"/> 
    <xsl:param name="range-2-begin" select="5"/> 
    <xsl:param name="range-2-end" select="6"/> 

    <xsl:template match="y:Table"> 
     <test> 
      <xsl:for-each select="y:Row"> 
       <xsl:if test="(position() &gt;= $range-1-begin and position() &lt;= $range-1-end)      or (position() &gt;= $range-2-begin and position() &lt;= $range-2-end)"> 
        <Row> 
         <xsl:for-each select="Cell"> 
          <xsl:if test="position() = 1 or position() = 3"> 
           <Cell> 
            <xsl:value-of select="."/> 
           </Cell> 
          </xsl:if> 
         </xsl:for-each> 
        </Row> 
       </xsl:if> 
      </xsl:for-each> 
     </test> 
    </xsl:template> 
</xsl:stylesheet> 
+0

這會讓我走得更遠,但它仍然包含大量正確輸出的XML上方和下方的空格(?)。我怎麼能告訴它只*輸出我需要的XML,即如何告訴XSL不要識別所有這些額外的輸出? – 2011-03-11 14:17:13

+0

@ Edward-Tanguay:很高興能提供幫助 - 歡迎您。也許你可以考慮接受答案? :) – 2011-03-11 14:19:00

+0

但它仍然無法工作100%:使用您的命名空間塊和y:Table,y:Row(並且我必須做ay:Cell更改),我在*中間得到正確的XML *是一個非常長的大多數空白文件和來自variou單元格的各種數據的文件,就好像它仍然不匹配XML文件中的名稱空間,但我甚至將它們一對一地複製,並且它仍然輸出相同的長文件有很多空白,這是從哪裏來的?例如, – 2011-03-11 14:23:27

2

測試XML和XSL不聲明和使用,而Excel的XML導出任何命名空間的定義不同的命名空間:

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" 
+0

我必須對我的XML/XSL文件做些什麼才能正確解析XSL文件這個XML文件的命名空間? – 2011-03-11 13:30:51