2017-10-28 208 views
0

任何指導我可以根據令牌將給定的xml元素值拆分爲多個子元素。這裏是我的示例輸入xml和所需的輸出。我有使用xsl 1.0的限制。謝謝。字符串使用XSL 1.0拆分爲新元素

輸入XML:

<?xml version='1.0' encoding='UTF-8'?> 
<SQLResults> 
    <SQLResult> 
     <ACTION1>Action1</ACTION1> 
     <ACTION2>Action2</ACTION2> 
     <Encrypt>Program=GPG;Code=23FCS;</Encrypt> 
     <SENDER>Program=WebPost;Protocol=WS;Path=/home/Inbound</SENDER> 
    </SQLResult> 
</SQLResults> 

輸出XML:

<?xml version='1.0' encoding='UTF-8'?> 
<SQLResults> 
    <SQLResult> 
     <ACTION1>Action1</ACTION1> 
     <ACTION2>Action2</ACTION2> 
     <Encrypt> 
      <Program>GPG</Program> 
      <Code>23FCS</Code> 
     </Encrypt> 
     <SENDER> 
      <Program>Action4</Program> 
      <Protocol>WS</Protocol> 
      <Path>/home/Inbound</Path> 
     </SENDER> 
    </SQLResult> 
</SQLResults> 
+0

嗯,首先檢查是否您的XSLT 1.0處理器不支持http://exslt.org/str/functions/tokenize/index.html,如果不,您仍然可以使用基於XSLT 1.0模板的實現http://exslt.org/str/functions/tokenize/str.tokenize.template.xsl。 –

+0

謝謝。我正在檢查。感謝您能否指出我具有上述功能的片段。 – GSR

回答

1

XSLT 2它會很容易,只需用下面的模板:

<xsl:template match="Encrypt|SENDER"> 
    <xsl:copy> 
    <xsl:analyze-string select="." regex="(\w+)=([\w/]+);?"> 
     <xsl:matching-substring> 
     <element name="{regex-group(1)}"> 
      <xsl:value-of select="regex-group(2)"/> 
     </element> 
     </xsl:matching-substring> 
    </xsl:analyze-string> 
    </xsl:copy> 
</xsl:template> 

因爲你w ^螞蟻在XSLT 1這樣做,你必須用另一種方式來表達。

而不是analyze-string你必須:

  • 令牌化內容爲包含;字符之間的非空令牌。 您必須添加tokenize模板。
  • 每個這樣的標記分成2個子字符串,在= char之前和之後。
  • 創建一個名稱與第一個子字符串相同的元素。
  • 編寫此元素的內容 - 第二個子字符串。

XSLT 1也有這樣的限制,即tokenize模板 的結果是一個結果樹片段(RTF)不是節點設置,因此它不能在XPath表達式中使用 。

要規避此限制,您必須使用exsl:node-set函數。

所以整個腳本看上去象下面這樣:

<?xml version="1.0" encoding="UTF-8" ?> 
<xsl:transform version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:exsl="http://exslt.org/common"> 
    <xsl:output method="xml" encoding="UTF-8" indent="yes" /> 
    <xsl:strip-space elements="*"/> 

    <xsl:template match="Encrypt|SENDER"> 
    <xsl:copy> 
     <xsl:variable name="tokens"> 
     <xsl:call-template name="tokenize"> 
      <xsl:with-param name="txt" select="."/> 
      <xsl:with-param name="delim" select="';'"/> 
     </xsl:call-template> 
     </xsl:variable> 
     <xsl:for-each select="exsl:node-set($tokens)/token"> 
     <xsl:variable name="t1" select="substring-before(., '=')"/> 
     <xsl:variable name="t2" select="substring-after(., '=')"/> 
     <xsl:element name="{$t1}"> 
      <xsl:value-of select="$t2" /> 
     </xsl:element> 
     </xsl:for-each> 
    </xsl:copy> 
    </xsl:template> 

    <xsl:template name="tokenize"> 
    <xsl:param name="txt" /> 
    <xsl:param name="delim" select="' '" /> 
    <xsl:choose> 
     <xsl:when test="$delim and contains($txt, $delim)"> 
     <token> 
      <xsl:value-of select="substring-before($txt, $delim)" /> 
     </token> 
     <xsl:call-template name="tokenize"> 
      <xsl:with-param name="txt" select="substring-after($txt, $delim)" /> 
      <xsl:with-param name="delim" select="$delim" /> 
     </xsl:call-template> 
     </xsl:when> 
     <xsl:when test="$txt"> 
     <token><xsl:value-of select="$txt" /></token> 
     </xsl:when> 
    </xsl:choose> 
    </xsl:template> 

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

非常感謝您的解釋。這是我的工作。再次感謝你。 – GSR