2014-05-20 35 views
3

我遇到了另一位工程師的問題。作爲一名新工程師,我必須找出解決方案,但我一直無法做到。任何幫助將不勝感激,我發現最接近的東西是Chunk string with XSLT,但仍然不是那裏。我只能使用XSL v1.0。XSLT:讀取作爲字符串傳遞的xml文檔的參數

參數作爲巨大的字符串傳遞給我的樣式表。它最初來自XML文檔。字符串看起來像這樣。

With <xsl:value-of select="$servers"/>其中$servers是傳遞給我的字符串的參數。該字符串看起來是這樣的:

<license><active_servers><server><name>MIKE</name><capacity>18</capacity><status>0</status><expiration></expiration><left>0</left><comment></comment></server><server><name>Susie</name><capacity>0</capacity><status>1</status><expiration>2014-07-04T00:00:00Z</expiration><left>5238568</left><comment></comment></server><server><name>Zoe</name><capacity>5000</capacity><status>1</status><expiration></expiration><left>0</left><comment></comment></server></active_servers></license>

這是作爲一個參數去樣式表傳遞的XML數據的一部分。實際文檔有300行左右的數據。區分這些「節點」的唯一區別是<server></server>。如果它是一個非常大的字符串,是否有辦法將數據從這裏拉出來?例如,可以說例如:

。我需要找到「佐伊」,看看她是否有「過期」,如果她沒有,我需要她的「身份」。所以Zoe將會顯示「1」狀態,因爲她沒有到期。雖然MIKE將顯示「0」,Susie將顯示2014-07-04T00:00:00Z。

我已經瀏覽了谷歌和堆棧溢出找到一個解決方案來解析/閱讀一個巨大的字符串。但是,我還沒有找到足夠接近的解決方案,在那裏我可以做到這一點。截至目前,我被卡在沒有工作副本,2天沒有得到任何地方的研究。

+0

字符串不是XMl,不能被解析爲XML。有沒有辦法將*路徑*作爲參數傳遞給實際的XML文檔? –

+0

我4天前通過電子郵件向世界各地的其他工程師發送電子郵件,但沒有收到回覆。所以我認爲,這是他想要的方式。我想也許我錯過了能夠讀取像這樣的字符串的東西。我知道我可以測試某個關鍵詞的字符串,比如MIKE或Zoe,但我認爲我無法測試關鍵字後面的數據,我是否正確? – misterbear

+0

您可以使用XSLT 1.0提供的字符串函數將字符串*解析爲字符串*,這將非常繁瑣且容易出錯。您應該努力將輸入*處理爲XML *,這意味着(1)訪問XML文件中的原始數據;或(2)連續進行兩次轉換,第一次轉換將參數保存到具有已知路徑的文件中,並從該文件中讀取第二次轉換。 –

回答

2

字符串不是XML,不能被解析爲作爲XML。您當然可以使用由XSLT 1.0提供的字符串函數將字符串解析爲字符串 - 這會非常繁瑣且容易出錯。

如果可能,將路徑作爲參數傳遞給實際的XML文檔。或者,調用兩個串行轉換,第一個轉換將參數保存爲具有已知路徑的文件,並從該文件讀取第二個轉換。

參見:
https://stackoverflow.com/a/14512924/3016153

3

這是不可能解析字符串爲XML,如@ michael.hor257k在接受的答案正確觀察,但有的方式來對待你的字符串作爲節點 - 通過加載它作爲嵌入式文檔。這可以使用data URI schemedocument()函數。但是,XSLT 1.0 Specification警告說,這是依賴於實現的(處理器不需要支持任何uri方案)。我使用Xalan和Saxon 6等XSLT 1.0處理器測試了它,並且它工作正常。

解決方法是將字符串附加到用逗號分隔的數據URI方案data:text/xml。然後,您可以將此字符串傳遞給你的document()功能,它會解析它作爲一個XML文件:

document(concat('data:text/xml,',$servers)) 

然後,您可以應用任何模板的節點集合。

這是一個樣式表,其中包含$servers參數,該參數應接收包含XML數據的字符串。它將解析字符串,模板變換節點,併產生一些數據的XML輸出:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:output indent="yes"/> 
    <xsl:param name="servers"/> 

    <xsl:template match="/"> 
     <xsl:apply-templates select="document(concat('data:text/xml,',$servers))/license"/> 
    </xsl:template> 

    <xsl:template match="license"> 
     <results> 
      <xsl:apply-templates/> 
     </results> 
    </xsl:template> 

    <!-- server without expiration - get status --> 
    <xsl:template match="server[not(string(expiration))]"> 
     <server name="{name}" status="{status}" /> 
    </xsl:template> 

    <!-- server with expiration - get expiration --> 
    <xsl:template match="server"> 
     <server name="{name}" expiration="{expiration}" /> 
    </xsl:template> 

</xsl:stylesheet> 

如果您有任何來源的運行它,並將其作爲參數數據傳給你:

<results> 
    <server name="MIKE" status="0"/> 
    <server name="Susie" expiration="2014-07-04T00:00:00Z"/> 
    <server name="Zoe" status="1"/> 
</results> 

UPDATE:此功能還依賴於解析器支持數據uris。我沒有意識到這一點,因爲我的XML環境有這種支持,所以更改不同的XSLT處理器並沒有什麼區別。我在Mac OS X環境中使用了Oxygen XML Editor 15.2。當我發現它正在使用的解析器時,我會更新這些信息。

+0

這是一個有趣的想法,但是我無法在任何處理器上重現您的成功。使用Saxon和Xalan時,我會收到「格式錯誤的URL」警告。你能否在這裏更正這個例子:http://xsltransform.net/bFukv8r –

+0

@ michael.hor257k它似乎也依賴於解析器對data-uri的支持。它在Oxygen XML Editor 15.2(和共享相同配置的命令行環境)中工作,但我無法使它與標準的Java 8 TraX實現兼容。 – helderdarocha

相關問題