基于动态正则表达式的XPath搜索

时间:2009-02-12 02:36:10

标签: java xml xslt xpath xpath-2.0

我有一个类似下面的XML:

    <?xml version="1.0" encoding="UTF-8"?>
    <Configuration>
        <Destinations>
            <Destination name="DEST1" >
                <From>AMA*</From>
            </Destination>

            <Destination name="DEST2" >
                <From>AMAZON</From>
            </Destination>

                           <Destination name="DEST3" >
                <From>EBAY</From>
            </Destination>

                           <Destination name="DEST4" >
                <From>*</From>
            </Destination>

        </Destinations>
    </Configuration>

我想查询并找出与提供的输入匹配的所有设计。

如果我指定EBAY我希望xpath返回节点名称= DEST3和DEST4(它不关心该值)但是如果我指定AMAZON它需要返回DEST1,DEST2和DEST4作为DEST1中的AMA *支持外卡人物。

到目前为止,我的XPath看起来像这样:

  

/目的地[(From =' '或   从='*'))] / @ name

如果指定了输入,我会动态创建XPATH表达式并将输入值插入 字段

除了From之外,我的XML中还有其他元素。

感谢是否有人可以指出这一点。

谢谢, Manglu

1 个答案:

答案 0 :(得分:7)

以下XPath 2.0表达式表达了所需的选择

  /*/*/*[From[matches($pPat, replace(., '\*', '.*'))]]

<强>解释

  1. $pPat 变量包含搜索模式(例如'EBAY','AMAZON'等)。

  2. 标准XPath 2.0函数matches()用于将任何From元素的值与字符串模式匹配。

  3. 任何From元素的值都将转换为XPath 2.0支持的标准正则表达式。为此,'*'(为"\*"转义,以便不被视为正则表达式中使用的特殊字符'*',而是作为普通字符)被".*"替换为字符串{ {1}}

  4. <强>测试

    我使用了以下XSLT 2.0转换并验证了上面的XPath 2.0表达式按预期选择了元素。要使用它,请将全局参数$ pPat的值替换为任何所需的值。

    <xsl:stylesheet version="2.0"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:xs="http://www.w3.org/2001/XMLSchema">
        <xsl:output omit-xml-declaration="yes"/>
    
        <xsl:param name="pPat" as="xs:string"
         select="'AMAZON'"/>
    
        <xsl:variable name="vsrchResult" as="element()*"
         select="/*/*/*[From[matches($pPat, replace(., '\*', '.*'))]]"/>
    
        <xsl:template match="/">
          <xsl:copy-of select="$vsrchResult"/>
        </xsl:template>
    </xsl:stylesheet>
    

    将此转换应用于最初提供的XML文档

    <Configuration>
        <Destinations>
            <Destination name="DEST1" >
                <From>AMA*</From>
            </Destination>
            <Destination name="DEST2" >
                <From>AMAZON</From>
            </Destination>
            <Destination name="DEST3" >
                <From>EBAY</From>
            </Destination>
            <Destination name="DEST4" >
                <From>*</From>
            </Destination>
        </Destinations>
    </Configuration>
    

    生成所需的输出

    <Destination name="DEST1">
                <From>AMA*</From>
            </Destination><Destination name="DEST2">
                <From>AMAZON</From>
            </Destination><Destination name="DEST4">
                <From>*</From>
            </Destination>