2011-07-25 33 views
2

得到的數據是否有可能第二個符號;後得到的數據? 例如,我有這樣的XML:如何從動態記錄

<document> 
    <line>H;1F;ss;232</line> 
    <line>H2;1F;sss;232e</line> 
    <line>H;15F5;sds;232sa;23</line> 
    <line>Hh;1Fs;scs;232ds</line> 
</document> 

的結果應該是:

<document> 
    <line>ss</line> 
    <line>sss</line> 
    <line>sds</line> 
    <line>scs</line> 
</document> 
+0

好問題, +1。查看我對兩種解決方案的回答:使用FXSL和XSLT 2.0解決方案的XSLT 1.0解決方案。提供了廣泛的解釋和FXSL鏈接。 –

+0

我的回答對你有用嗎?或者您在應用該解決方案時遇到任何問題?如果是的話,這些問題是什麼? –

+0

@Dimitre Novatchet:謝謝你的回答,這是我需要的。因爲我有大約10個符號「;」而且很難用子串來查找它 - 之前和之後。 – Petras

回答

2

I的XSLT 1.0溶液使用FXSL

這種變換:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:ext="http://exslt.org/common" 
    exclude-result-prefixes="ext"> 
    <xsl:import href="strSplit-to-Words.xsl"/> 
    <xsl:output indent="yes" omit-xml-declaration="yes"/> 
    <xsl:strip-space elements="*"/> 

    <xsl:template match="/*"> 
    <document> 
     <xsl:apply-templates/> 
    </document> 
    </xsl:template> 

    <xsl:template match="line"> 
     <xsl:variable name="vwordNodes"> 
     <xsl:call-template name="str-split-to-words"> 
      <xsl:with-param name="pStr" select="."/> 
      <xsl:with-param name="pDelimiters" 
          select="';'"/> 
     </xsl:call-template> 
     </xsl:variable> 

     <line> 
     <xsl:value-of select="ext:node-set($vwordNodes)/*[3]"/> 
     </line> 
    </xsl:template> 
</xsl:stylesheet> 

當所提供的XML文檔施加:

<document> 
    <line>H;1F;ss;232</line> 
    <line>H2;1F;sss;232e</line> 
    <line>H;15F5;sds;232sa;23</line> 
    <line>Hh;1Fs;scs;232ds</line> 
</document> 

產生想要的,正確結果

<document> 
    <line>ss</line> 
    <line>sss</line> 
    <line>sds</line> 
    <line>scs</line> 
</document> 

說明

  1. 我們使用來自FXSLstr-split-to-words模板拆分每line元素的字符串值。注意,它allowis不僅是單個字符,但多個字符將在其pDelimiters參數中指定。在這種情況下,我們只指定​​3210。

  2. 結果顯示在一個變量作爲RTF捕獲。我們使用ext:node-set()擴展函數將其轉換爲普通樹。如果您的XSLT處理器未執行ext:node-set(),請查看其文檔中此特定XSLT處理器實現的xxx:node-set()擴展名的名稱和名稱空間。

  3. 從如此獲得的樹中,我們只選擇並輸出所述第三元件。請注意,這是一個簡短的XPath表達式,即使我們想要第20個元素,也會使用相同的簡短XPath表達式 - 只是索引爲20.這不可能在短而整齊的情況下使用一系列的substring-after()功能。

二,這是一個簡單而容易的XSLT 2。0解決方案

<xsl:stylesheet version="2.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output omit-xml-declaration="yes" indent="yes"/> 

<xsl:template match="/*"> 
    <document> 
     <xsl:apply-templates/> 
    </document> 
</xsl:template> 

<xsl:template match="line"> 
    <document> 
    <xsl:value-of select="tokenize(., ';')[3]"/> 
    </document> 
</xsl:template> 
</xsl:stylesheet> 

當這種轉變是在所提供的XML文檔應用。查閱全文:

<document> 
    <line>H;1F;ss;232</line> 
    <line>H2;1F;sss;232e</line> 
    <line>H;15F5;sds;232sa;23</line> 
    <line>Hh;1Fs;scs;232ds</line> 
</document> 

想要的,正確的結果產生

<document> 
     <document>ss</document> 
     <document>sss</document> 
     <document>sds</document> 
     <document>scs</document> 
</document> 
+0

我打消了我的XSLT 2.0的答案,因爲使用tokenize'的'顯然更適合這裏。 XSLT 1.0也提供了很好的替代方案。 +1 –

2

使用substring-beforesubstring-after功能,即:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

    <xsl:template match="node() | @*"> 
     <xsl:copy> 
      <xsl:apply-templates select="node() | @*" /> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="line"> 
     <xsl:copy> 
      <xsl:value-of select="substring-before(substring-after(substring-after(., ';'), ';'), ';')"/> 
     </xsl:copy> 
    </xsl:template> 

</xsl:stylesheet> 

結果:

<document> 
    <line>ss</line> 
    <line>sss</line> 
    <line>sds</line> 
    <line>scs</line> 
</document> 
+0

找不到「;」的第二個位置避免之前和之後的子串? – Petras

+0

@Petras,所有的XPath 1.0字符串函數:http://www.w3.org/TR/xpath/#section-String-Functions –

+0

@Petras,我認爲沒有XSLT 1.0的方法來簡化這個表達式,除非你使用EXSLT。 –