2017-06-21 54 views
0

如何替換XML中的CData元素下的字符串? 在這裏,我想匹配2個條件如下圖所示:在XML中搜索字符串,其結尾與一個子字符串匹配幷包含另一個子字符串

<xsl:template match="@*[ends-with((local-name(),'mustEndWithThisSubstring'))] and not(contains((local-name(),'mustContainThisSubstring')))" > 

1 - 如何有多個條件爲「XSL:匹配」部分

2-如何用期望的字符串(已知)替換匹配的字符串(未知)?

查看下面的代碼片段。

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" cdata- 
section-elements=replacingWith"/> 
<xsl:strip-space elements="*"/> 

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

<xsl:template match="@*[ends-with((local-name(),'mustEndWithThisSubstring'))] and not(contains((local-name(),'mustContainThisSubstring')))" > 
    <xsl:copy> 
      <replacingWith"/> 
         <xsl:value-of select="substring-after(., '&lt;foundStringThatMatchesConditions>'), '&lt;/foundStringThatMatchesConditions>')"/> 
      </replacingWith> 
    </xsl:copy> 
    </xsl:template> 
</xsl:stylesheet> 

輸入:

<soap:Body> 
    <pre:getResponse> 
    <![CDATA[ 
      <foundStringThatMatchesConditions> 
    ....... 
      </foundStringThatMatchesConditions> 
    ]]> 
</pre:getResponse> 
</soap:Body> 

輸出:

<soap:Body> 
    <pre:getResponse> 
     <![CDATA[ 
       <replacingWith> 
     ....... 
      </replacingWith> 
     ]]> 
</pre:getResponse> 
</soap:Body> 
+2

你應該知道[你的上一個問題](https://stackoverflow.com/questions/44532804/move-an-xml-element-from-its-place-to-under-another-parent-element-using -xslt)表示CDATA的內容只是一個無意義的字符串,XPath表達式除了字符串函數之外無法解決這個問題。即使目標是真正的XML樹,您的XPath表達式也不會有多大意義。 –

回答

1

我如何替換字符串,它是在一個XML CDATA元素下?

確切地說,您替換任何其他文本節點的值中的字符串的方式。也就是說,在從輸入文檔中的CDATA部分獲得的字符數據與其他字符數據之間進行分析之後,沒有進行區分。所有表示爲XSLT也使用的XPath數據模型中的文本節點。實際上,它們可以合併,因此沒有文本節點將另一個文本節點作爲緊隨其後的兄弟節點。 text()是專門匹配文本節點的節點測試。

請特別注意,就XSLT而言,CDATA節的內容沒有結構。在使用CDATA將XML嵌入到另一個XML文檔中的情況下,該部分的內容不能像XML一樣直接訪問。對於主機文檔的目的,它們不是。

XSLT 1.0沒有用於子字符串搜索和替換的內置函數,但是您可以通過模板來做到這一點 - 只需付出一點努力即可。請參閱substring-before(),substring-after()和函數。

你也問,

1 - 如何有多個條件:部分 「XSL匹配」?

您可以提供多個謂詞或使用布爾運算符來組合相同謂詞中的條件。例如,

<xsl:template match="@*[ends-with(local-name(),'mustEndWithThisSubstring') and not(contains(local-name(),'mustContainThisSubstring'))]" > 

<xsl:template match="@*[ends-with(local-name(),'mustEndWithThisSubstring')][not(contains(local-name(),'mustContainThisSubstring'))]" > 

當關系運算符是and,這兩種形式具有類似的但不相同,語義。但請注意,這些特定表達式與屬性@*)匹配,它們不能包含CDATA或包含在CDATA中。

2-如何用期望的 字符串(已知)替換匹配的字符串(未知)?

您可能不知道事先該字符串進行匹配,但你肯定知道其中的文本正在對匹配的相關模板的上下文。在上面的表達式中,它是local-name()函數的返回值。如果您願意,您可以將其捕獲到一個變量中,或者將其作爲參數傳遞給另一個模板。正如我已經說過的,可以編寫一個模板來處理字符串替換的工作。細節留作練習。

相關問題