xml搜索并替换xsl错误

时间:2017-06-14 07:28:43

标签: xml xslt xslt-2.0

<?xml version="1.0" encoding="UTF-8"?>
<TABLE NAME="less.db">
   <DATA RECORDS="233673">
      <RECORD ID="1">
         <ID>1</ID>
         <ROW>0</ROW>
         <DATE>19/9/2003 12:31:54 μμ</DATE>
         <al>29/6/2005 10:46:42 πμ</al>
         <KIT>46123</KIT>
         <KAP>08</KAP>
         <YTE>A.IV.C.54</YTE>
         <HTE>0</HTE>
         <HEN>0</HEN>
         <SUM>0</SUM>
         <LYW>0</LYW>
         <AMF>29</AMF>
         <MANUFACTURER>ASUS</MANUFACTURER>
         <AME>pan</AME>
      </RECORD>
      <RECORD ID="1">
         <ID>1</ID>
         <ROW>0</ROW>
         <DATE>19/9/2003 12:31:54 μμ</DATE>
         <al>29/6/2005 10:46:42 πμ</al>
         <KIT>46123</KIT>
         <KAP>08</KAP>
         <YTE>A.IV.C.54</YTE>
         <HTE>0</HTE>
         <HEN>0</HEN>
         <SUM>0</SUM>
         <LYW>0</LYW>
         <AMF>29</AMF>
         <MANUFACTURER>asus</MANUFACTURER>
         <AME>pan</AME>
      </RECORD>
      <RECORD ID="14">
         <ID>1</ID>
         <ROW>0</ROW>
         <DATE>19/9/2003 12:31:54 μμ</DATE>
         <al>29/6/2005 10:46:42 πμ</al>
         <KIT>46123</KIT>
         <KAP>08</KAP>
         <YTE>A.IV.C.54</YTE>
         <HTE>0</HTE>
         <HEN>0</HEN>
         <SUM>0</SUM>
         <LYW>0</LYW>
         <AMF>29</AMF>
         <MANUFACTURER>Creative Labs</MANUFACTURER>
         <AME>pan</AME>
      </RECORD>
      <RECORD ID="1">
         <ID>1</ID>
         <ROW>0</ROW>
         <DATE>19/9/2003 12:31:54 μμ</DATE>
         <al>29/6/2005 10:46:42 πμ</al>
         <KIT>46123</KIT>
         <KAP>08</KAP>
         <YTE>A.IV.C.54</YTE>
         <HTE>0</HTE>
         <HEN>0</HEN>
         <SUM>0</SUM>
         <LYW>0</LYW>
         <AMF>29</AMF>
         <MANUFACTURER>Creative</MANUFACTURER>
         <AME>pan</AME>
      </RECORD>
      <RECORD ID="14">
         <ID>1</ID>
         <ROW>0</ROW>
         <DATE>19/9/2003 12:31:54 μμ</DATE>
         <al>29/6/2005 10:46:42 πμ</al>
         <KIT>46123</KIT>
         <KAP>08</KAP>
         <YTE>A.IV.C.54</YTE>
         <HTE>0</HTE>
         <HEN>0</HEN>
         <SUM>0</SUM>
         <LYW>0</LYW>
         <AMF>29</AMF>
         <MANUFACTURER>This is a test. Replace (all)</MANUFACTURER>
         <AME>pan</AME>
      </RECORD>
   </DATA>
</TABLE>

search.txt:

ASUS
creative
This is a test. Replace (all)

replace.txt

GIGABYTE
LOGITECH
REPLACEMENT

和xsl:

<?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="MANUFACTURER[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>

输出如下:

<?xml version="1.0" encoding="UTF-8"?>
 <TABLE NAME="less.db">
   <DATA RECORDS="233673">
      <RECORD ID="1">
         <ID>1</ID>
         <ROW>0</ROW>
         <DATE>19/9/2003 12:31:54 μμ</DATE>
         <al>29/6/2005 10:46:42 πμ</al>
         <KIT>46123</KIT>
         <KAP>08</KAP>
         <YTE>A.IV.C.54</YTE>
         <HTE>0</HTE>
         <HEN>0</HEN>
         <SUM>0</SUM>
         <LYW>0</LYW>
         <AMF>29</AMF>
         <MANUFACTURER>GIGABYTE</MANUFACTURER>
         <AME>pan</AME>
      </RECORD>
      <RECORD ID="1">
         <ID>1</ID>
         <ROW>0</ROW>
         <DATE>19/9/2003 12:31:54 μμ</DATE>
         <al>29/6/2005 10:46:42 πμ</al>
         <KIT>46123</KIT>
         <KAP>08</KAP>
         <YTE>A.IV.C.54</YTE>
         <HTE>0</HTE>
         <HEN>0</HEN>
         <SUM>0</SUM>
         <LYW>0</LYW>
         <AMF>29</AMF>
         <MANUFACTURER>GIGABYTE</MANUFACTURER>
         <AME>pan</AME>
      </RECORD>
      <RECORD ID="14">
         <ID>1</ID>
         <ROW>0</ROW>
         <DATE>19/9/2003 12:31:54 μμ</DATE>
         <al>29/6/2005 10:46:42 πμ</al>
         <KIT>46123</KIT>
         <KAP>08</KAP>
         <YTE>A.IV.C.54</YTE>
         <HTE>0</HTE>
         <HEN>0</HEN>
         <SUM>0</SUM>
         <LYW>0</LYW>
         <AMF>29</AMF>
         <MANUFACTURER>LOGITECH Labs</MANUFACTURER>
         <AME>pan</AME>
      </RECORD>
      <RECORD ID="1">
         <ID>1</ID>
         <ROW>0</ROW>
         <DATE>19/9/2003 12:31:54 μμ</DATE>
         <al>29/6/2005 10:46:42 πμ</al>
         <KIT>46123</KIT>
         <KAP>08</KAP>
         <YTE>A.IV.C.54</YTE>
         <HTE>0</HTE>
         <HEN>0</HEN>
         <SUM>0</SUM>
         <LYW>0</LYW>
         <AMF>29</AMF>
         <MANUFACTURER>LOGITECH</MANUFACTURER>
         <AME>pan</AME>
      </RECORD>
      <RECORD ID="14">
         <ID>1</ID>
         <ROW>0</ROW>
         <DATE>19/9/2003 12:31:54 μμ</DATE>
         <al>29/6/2005 10:46:42 πμ</al>
         <KIT>46123</KIT>
         <KAP>08</KAP>
         <YTE>A.IV.C.54</YTE>
         <HTE>0</HTE>
         <HEN>0</HEN>
         <SUM>0</SUM>
         <LYW>0</LYW>
         <AMF>29</AMF>
         <MANUFACTURER>REPLACEMENT</MANUFACTURER>
         <AME>pan</AME>
      </RECORD>
   </DATA>
</TABLE>

如何制作使用过的xsl,以便进行精确搜索和替换? 例如,LOGITECH Labs是一个不受欢迎的替代品。我们想要只更换具有完全单词creative(不区分大小写的替换)的每个元素,而不是在MANUFACTURER元素中找到的任何地方

1 个答案:

答案 0 :(得分:0)

我认为错误可能是由包含多个搜索词的元素引起的,这里是一个改编的代码示例,希望不会给出错误:

<?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="MANUFACTURER[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[index-of($search-terms-is, $t)]"/>
            <xsl:value-of
                select="functx:replace-multi(., $matched-terms, $replacements, 'i')"/>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>