XPath search based on dynamic regular expressions

心已入冬 提交于 2019-12-10 10:39:37

问题


I have an XML like the one below:

    <?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>

I want to query and find out all desintations that match a provided input.

If i specify EBAY i want the xpath to return the node name = DEST3 and DEST4 (which doesn't care about the value) but if i specify AMAZON it needs to return DEST1, DEST2 and DEST4 as AMA* in DEST1 supports wild card character.

so far my XPath looks like this:

/Destination[(From = '' or From = '*' ) )]/@name

If input is specified i create the XPATH expressions dynamically and slot the incoming value in the field

I have other elements in my XML besides From.

Appreciate if anyone could give pointers on this.

Thanks, Manglu


回答1:


The following XPath 2.0 expression expresses the required selection:

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

Explanation:

  1. The $pPat variable contains the search pattern (such as 'EBAY', 'AMAZON', etc.).

  2. The standard XPath 2.0 function matches() is used to match the value of any From element to the string pattern.

  3. The value of any From element is converted to a standard regular expression as supported by XPath 2.0. For this purpose, any occurence of '*' (escaped as "\*" in order not to be taken as the special char '*' used in regexs but as a normal character) is replaced by the string ".*"

Testing:

I have used the following XSLT 2.0 transformation and verified that the above XPath 2.0 expression selects the elements as expected. To use it, replace the value of the global parameter $pPat with any desired value.

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

When this transformation is applied on the originally-provided XML document:

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

the required output is produced:

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


来源:https://stackoverflow.com/questions/539781/xpath-search-based-on-dynamic-regular-expressions

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!