在XML中搜索与其结尾匹配的字符串和一个子字符串,并包含另一个子字符串

时间:2017-06-21 17:07:48

标签: xml xslt

如何替换XML中CData元素下的字符串?  在这里,我试图匹配以下2个条件:

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

1-如何为“xsl:match”部分设置多个条件

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>

1 个答案:

答案 0 :(得分:1)

  

如何替换XML中CData元素下的字符串?

正是您在任何其他文本节点的值中替换字符串的方式。也就是说,在从输入文档中的CDATA部分获得的字符数据与其他字符数据之间进行解析之后,没有区别。所有都表示为XSLT也使用的XPath数据模型中的文本节点。实际上,它们需要合并,以便没有文本节点具有另一个文本节点作为紧随其后的兄弟节点。 text()是一个特定匹配文本节点的节点测试。

特别注意,就XSLT而言,CDATA部分的内容没有任何结构。如果使用CDATA将XML嵌入到另一个XML文档中,则无法(直接)访问该部分的内容,就像它们是XML一样。出于主持人文档的目的,他们不是。

XSLT 1.0没有用于子字符串搜索和替换的内置函数,但您可以通过模板进行一些努力。请参阅substring-before()substring-after()contains()函数。

你也问,

  

1-如何为&#34; xsl:match&#34;设置多个条件部分?

您可以提供多个谓词或使用布尔运算符来组合同一谓词中的条件。例如,

<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中。

  

2-如何用所需的(未知)替换匹配的字符串   字符串(已知)?

您可能不知道提前将匹配哪个字符串,但您肯定知道在相关模板的上下文中正在匹配哪个文本。在上面的表达式中,它是local-name()函数的返回值。如果您愿意,可以在变量中捕获它或将其作为参数传递给另一个模板。正如我已经说过的,可以编写一个模板来处理字符串替换的工作。细节留作练习。