2017-09-04 18 views
0

我有源,类似下面:编辑一个xml文件 - 从文件中获取的搜索值,从第二个文件中获取替换值。搜索必须是不区分大小写

 <?xml version="1.0"?> 
<TABLE NAME="TEST"> 
<DATA RECORDS="78"> 
<catalog> 
    <book id="bk109"> 
     <description>An anthology of horror stories about roaches, centipedes, scorpions and other insects.</description> 
    </book> 
    <book id="bk110"> 
     <description>Microsoft's .NET initiative is explored in detail in this deep programmer's reference.</description> 
    </book> 
    <book id="bk111"> 
     <description>An anthology of HORROR stories about roaches, centipedes, scorpions and other insects.</description> 
    </book> 
    <book id="bk112"> 
     <description>An anthology of horror stories about roaches, centipedes, scorpions and other insects.</description> 
    </book> 
    <book id="bk113"> 
     <description>An anthology of horror stories about roaches, centipedes, scorpions and other insects.</description> 
    </book> 
    <book id="bk114"> 
     <description>Microsoft's .NET initiative is explored in detail in this deep PROGRAMMER's reference.</description> 
    </book> 
    <book id="bk115"> 
     <description>An anthology of HORROR stories about roaches, centipedes, scorpions and other insects.</description> 
    </book> 
    <book id="bk116"> 
     <description>An anthology of horror stories about roaches, centipedes, scorpions and other insects. Beware, this must not be matched.</description> 
    </book> 
    <book id="bk114"> 
     <description>Microsoft's .NET initiative is explored in detail in this deep PROGRAMMER's reference. Beware, this must not be matched.</description> 
    </book> 
</DATA> 
</TABLE> 

search.txt文件包含:

An anthology of horror stories about roaches, centipedes, scorpions and other insects. 
Microsoft's .NET initiative is explored in detail in this deep programmer's reference. 

replace.txt文件包含:

Value we need to store in the (description) element. 
Another value we need to store in the (description) element. 

的搜索应该不区分大小写,

因此都是

<description>An anthology of horror stories about roaches, centipedes, scorpions and other insects.</description> 

<description>An anthology of HORROR stories about roaches, centipedes, scorpions and other insects.</description> 

应该匹配,更换,这样的结果XML看起来应该像:

<?xml version="1.0"?> 
<TABLE NAME="TEST"> 
<DATA RECORDS="78"> 
<catalog> 
    <book id="bk109"> 
     <description>Value we need to store in the (description) element.</description> 
    </book> 
    <book id="bk110"> 
     <description>Another value we need to store in the (description) element.</description> 
    </book> 
    <book id="bk111"> 
     <description>Value we need to store in the (description) element.</description> 
    </book> 
    <book id="bk112"> 
     <description>Value we need to store in the (description) element.</description> 
    </book> 
    <book id="bk113"> 
     <description>Value we need to store in the (description) element.</description> 
    </book> 
    <book id="bk114"> 
     <description>Another value we need to store in the (description) element.</description> 
    </book> 
    <book id="bk115"> 
     <description>Value we need to store in the (description) element.</description> 
    </book> 
    <book id="bk116"> 
     <description>An anthology of horror stories about roaches, centipedes, scorpions and other insects. Beware, this must not be matched.</description> 
    </book> 
    <book id="bk114"> 
     <description>Microsoft's .NET initiative is explored in detail in this deep PROGRAMMER's reference. Beware, this must not be matched.</description> 
    </book> 
</DATA> 
</TABLE> 

我试图与http://www.xqueryfunctions.com/没有运气,我有请注意,在搜索或替换值中可能会找到特殊字符,例如a。,pareentheses()等,并且需要完全匹配(不区分大小写的课程)才能进行替换,请参阅最后一个des剔除节点,即不被替换。

UPDATE: 什么我都试过了,也不行,如果替换字符串是没有一个字:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    xmlns:functx="http://www.functx.com" 
    exclude-result-prefixes="xs functx" 
    version="2.0"> 

    <xsl:param name="search-file" as="xs:string" select="'search.txt'"/> 
    <xsl:param name="replacement-file" as="xs:string" select="'replace.txt'"/> 


    <xsl:param name="search-terms" as="xs:string*" select="tokenize(unparsed-text($search-file), '\r?\n')"/> 

    <xsl:param name="search-terms-is" as="xs:string*" select="for $term in $search-terms return lower-case(functx:escape-for-regex($term))"/> 

    <xsl:param name="replace-terms" as="xs:string*" select="tokenize(unparsed-text($replacement-file), '\r?\n')"/> 

    <xsl:include href="http://www.xsltfunctions.com/xsl/functx-1.0-nodoc-2007-01.xsl"/> 

    <xsl:function name="functx:replace-multi" as="xs:string?" 
     xmlns:functx="http://www.functx.com"> 
     <xsl:param name="arg" as="xs:string?"/> 
     <xsl:param name="changeFrom" as="xs:string*"/> 
     <xsl:param name="changeTo" as="xs:string*"/> 
     <xsl:param name="flags" as="xs:string"/> 

     <xsl:sequence select=" 
      if (count($changeFrom) > 0) 
      then functx:replace-multi(
      replace($arg, $changeFrom[1], 
      functx:if-absent($changeTo[1],''), $flags), 
      $changeFrom[position() > 1], 
      $changeTo[position() > 1]) 
      else $arg 
      "/> 

    </xsl:function> 

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

    <xsl:template match="description[some $search-term in $search-terms-is satisfies matches(current(), $search-term, 'i')]"> 
     <xsl:copy> 
      <xsl:variable name="matched-terms" as="xs:string*" select="$search-terms-is[matches(current(), ., 'i')]"/> 
      <xsl:variable name="replacements" as="xs:string*" select="for $t in $matched-terms return $replace-terms[position() = index-of($search-terms-is, $t)]"/> 
      <xsl:value-of 
       select="functx:replace-multi(., $matched-terms, $replacements, 'i')"/> 
     </xsl:copy> 
    </xsl:template> 

</xsl:stylesheet> 
+0

那么,你想要使用XSLT,所以你需要编写一个匹配你的搜索文本的匹配'description'元素的模板(你可以用文件中的'unparsed-text'来引入)。至于没有找到不区分大小写的匹配函数,为什么https://www.w3.org/TR/xpath-functions/#func-matches与'i'标志不适合你? –

+0

至于特殊字符,如果你已经找到http://www.xsltfunctions.com/xsl/functx_escape-for-regex.html你应该可以使用它。唯一的问题是,看到您的输入数据是有分行符,而您的搜索文本似乎没有它们。但规范化空间可能会有所帮助。 –

+0

@MartinHonnen ii更新了代码,并删除了符合条件的换行符。任何帮助将不胜感激 –

回答

0

鉴于你的样品和解释,我觉得一个description元素只能匹配曾经如此我觉得你的代码将正常工作具有以下的简化:

<xsl:param name="search-terms-is" as="xs:string*" select="for $term in $search-terms return concat('^', lower-case(functx:escape-for-regex($term)), '$')"/> 

<xsl:template match="description[some $search-term in $search-terms-is satisfies matches(., $search-term, 'i')]"> 
    <xsl:copy> 
     <xsl:variable name="matched-term" as="xs:string" select="$search-terms-is[matches(current(), ., 'i')]"/> 
     <xsl:variable name="replacement" as="xs:string" select="$replace-terms[index-of($search-terms-is, $matched-term)]"/> 
     <xsl:value-of 
      select="$replacement"/> 
    </xsl:copy> 
</xsl:template> 

至于一个更完整的例子,这里是一个负的外部文件:

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    xmlns:functx="http://www.functx.com" 
    exclude-result-prefixes="xs functx"> 

    <xsl:param name="search-text" as="xs:string">An anthology of horror stories about roaches, centipedes, scorpions and other insects. 
Microsoft's .NET initiative is explored in detail in this deep programmer's reference.</xsl:param> 

    <xsl:param name="replacement-text" as="xs:string">Value we need to store in the (description) element. 
Another value we need to store in the (description) element.</xsl:param> 

    <xsl:param name="search-terms" as="xs:string*" select="tokenize($search-text, '\r?\n')"/> 

    <xsl:param name="search-terms-is" as="xs:string*" select="for $term in $search-terms return concat('^', lower-case(functx:escape-for-regex($term)), '$')"/> 

    <xsl:param name="replace-terms" as="xs:string*" select="tokenize($replacement-text, '\r?\n')"/> 

    <xsl:include href="http://www.xsltfunctions.com/xsl/functx-1.0-nodoc-2007-01.xsl"/> 

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


<xsl:template match="description[some $search-term in $search-terms-is satisfies matches(., $search-term, 'i')]"> 
    <xsl:copy> 
     <xsl:variable name="matched-term" as="xs:string" select="$search-terms-is[matches(current(), ., 'i')]"/> 
     <xsl:variable name="replacement" as="xs:string" select="$replace-terms[index-of($search-terms-is, $matched-term)]"/> 
     <xsl:value-of 
      select="$replacement"/> 
    </xsl:copy> 
</xsl:template> 

</xsl:transform> 

在线在http://xsltransform.net/gVhD8RA

+0

之后我来测试,因为它不清楚,请你更新示例代码到一个完整的片段?谢谢 –

+0

我相信你可以自己测试一下,只需替换参数的那一行就可以了,如图所示替换一个模板。你的样式表的其余部分看起来很好,除了看起来你不需要'functx:replace-multi'这个函数。 –

+0

我已经添加了一个完整的XSLT样式表,当然在你真实的情况下,你想用'unparsed-text'从外部文件加载搜索和替换文本,但是你已经知道如何做到这一点,以适应这些行。 –

相关问题