2017-07-26 41 views
1

我試圖使用XSLT將.ods文件(來自zip的content.xml文件)轉換爲所需的.xml文件。如何在XSLT中獲取任何類型的特定.ODS單元格的內容

XSLT使用元素的「固定」位置來獲取內容,但在我的.ods文件中,我有很多空白字段,我不知道如何使它們在XSLT中計數。

此外,我用content.xml做了一些實驗,以確定這些空白單元是否被保存。

content.xml我發現是這樣的:

<table:table-column table:style-name="co1" table:number-columns-repeated="16384" table:default-cell-style-name="ce1"/> 
<table:table-row table:number-rows-repeated="1048576" table:style-name="ro1"> 

難道這些值以某種方式(例如用數學計算)表示在.ods文件中的空單元格或值的實際位置?

我在這裏分享我的文檔對你有更清晰的想法

.ods例如:

enter image description here

這是我的XSLT文件:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:xs="http://www.w3.org/2001/XMLSchema" 
xmlns:fn="http://www.w3.org/2005/xpath-functions" 
xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" 
xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" 
xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" 
xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" 
xmlns:espd="urn:com:grow:espd:02.00.00" xmlns:cac="urn:X-test:UBL:Pre- 
award:CommonAggregate" xmlns:cbc="urn:X-test:UBL:Pre-award:CommonBasic" 


<xsl:output method="html" version="1.0" encoding="UTF-8" indent="yes"/> 

<xsl:template match="office:spreadsheet/table:table"> 
<xsl:variable name="test" select="table:table-row/table:table-cell"/> 
<p><xsl:value-of select="$test/text:p[1]"/></p> 
</xsl:template> 

和輸出是:

布拉克burak5 burak6 burak2 burak3 burak4 burak7 burak9 burak8 burak10

問:

如何通過應用獲得來自電池的單值content.xml
(例如:如何到達剛剛細胞D4?)

回答

1

如何通過應用上content.xml變換來從電池的單值?

.ods文件的content.xml XML數據以這種方式(總是與table:命名空間前綴)進行編碼:

  • 每個table-cell包含在table-row小號
  • table-cell s的編碼空與RLE (Run-Length-Encoding)表示爲number-columns-repeated="..."屬性,必須跳過但計數
  • table-row個s的編碼與RLE,也由number-rows-repeated="..."屬性表示
  • table-columns似乎纔剛剛開始

所以使用,以獲得特定的細胞,如D4 = 4:4table-row小號包括被跳過的那些已經被計數:

D4 = 4:4 = Get the fourth `table-row`, add one cell D1, then add number-columns-repeated="2" 

這是一些XSLT-1.0代碼(也具有2.0和3.0可以使用)與GetCellValue例子:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:xs="http://www.w3.org/2001/XMLSchema" 
xmlns:fn="http://www.w3.org/2005/xpath-functions" 
xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" 
xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" 
xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" 
xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" 
xmlns:espd="urn:com:grow:espd:02.00.00" 
xmlns:cac="urn:X-test:UBL:Pre-award:CommonAggregate" 
xmlns:cbc="urn:X-test:UBL:Pre-award:CommonBasic" exclude-result-prefixes="xs fn office style table text espd cac cbc"> 

<xsl:output method="html" version="4.0" encoding="UTF-8" indent="yes"/> 
<xsl:variable name="str" select="'x:1 y:4'" />    <!-- define some coord system --> 


    <xsl:template match="/office:document-content/office:body/office:spreadsheet/table:table"> 
    Table dimensions: <xsl:call-template name="GetDimensions" /> 
    Value at 5x8: <xsl:call-template name="GetCellValue"> 
     <xsl:with-param name="x" select="5" /> 
     <xsl:with-param name="y" select="8" /> 
    </xsl:call-template> 
    Value at 1x4: <xsl:call-template name="GetCellValue"> <!-- use string defined above --> 
     <xsl:with-param name="x" select="substring-after(substring-before($str,' '),'x:')" /> 
     <xsl:with-param name="y" select="substring-after($str,'y:')" /> 
    </xsl:call-template> 
    </xsl:template> 

    <xsl:template name="GetCellValue"> 
    <xsl:param name="x" /> 
    <xsl:param name="y" /> 
    <xsl:variable name="targetRow" select="table:table-row[sum(preceding-sibling::*/@table:number-rows-repeated) + position() - count(preceding-sibling::*/@table:number-rows-repeated)= $y]" /> 
    <xsl:variable name="targetCell" select="$targetRow/table:table-cell[sum(preceding-sibling::*/@table:number-columns-repeated) + position() - count(preceding-sibling::*/@table:number-columns-repeated) &lt;= $x]" /> 
    <xsl:copy-of select="$targetCell[last()]/text:p/text()" /> 
    </xsl:template> 

    <xsl:template name="GetDimensions"> 
    <xsl:variable name="firstRow" select="table:table-row[1]/table:table-cell" /> 
    <xsl:variable name="firstColumn" select="table:table-row" /> 
    <xsl:variable name="width" select="count($firstRow)+ sum($firstRow/@table:number-columns-repeated) - count($firstRow/@table:number-columns-repeated)" /> 
    <xsl:variable name="height" select="count($firstColumn)+ sum($firstColumn/@table:number-rows-repeated) - count($firstColumn/@table:number-rows-repeated)" /> 
    <xsl:value-of select="concat($width,'x',$height)" /> 
    </xsl:template> 

</xsl:stylesheet> 

輸出是:

Table dimensions: 5x12 
Value at 5x8: burak9 
Value at 1x4: burak4 

編輯:
我修改了一個xsl:call-template用於自定義格式的字符串輸入,例如, x:1 y:4

+0

非常感謝!幾件讓我困惑的事情,想象一下,你有一個包含大量信息的大文件,那麼這種方法是否可行?如果我必須選擇讓我們說100個固定位置如何接近?另一件我沒有提到的我需要在XSLT 2.0中進行轉換。 – Sojimanatsu

+0

@Sojimanatsu:是的。它也應該處理大文件。所以100個固定職位應該能夠像兩個一樣工作。它會變慢,但可能不會太慢​​。順便說一句,這個模板也適用於XSLT-2.0和3.0,只需更改編號;-)。 – zx485

+0

@Sojimanatsu:謝謝。 – zx485

相關問題