Поиск XPath на основе динамических регулярных выражений - PullRequest
2 голосов
/ 12 февраля 2009

У меня есть 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, поскольку AMA * в DEST1 поддерживает подстановочный знак.

пока мой XPath выглядит так:

/ Destination [(From = '' или От = '*'))] / @ name

Если указан вход, я динамически создаю выражения XPATH и помещаю входящее значение в поле

У меня есть другие элементы в моем XML, кроме From.

Цените, если кто-нибудь может дать указание на это.

Спасибо, Manglu

1 Ответ

7 голосов
/ 12 февраля 2009

Следующее выражение XPath 2.0 выражает требуемый выбор :

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

Объяснение

  1. Переменная $pPat содержит шаблон поиска (например, «EBAY», «AMAZON» и т. Д.).

  2. Стандартная функция XPath 2.0 matches() используется для сопоставления значения любого элемента From с шаблоном строки.

  3. Значение любого элемента From преобразуется в стандартное регулярное выражение, поддерживаемое XPath 2.0. Для этой цели любой случай '*' (экранируется как "\*", чтобы его не воспринимали как специальный символ '*', используемый в регулярных выражениях, но как обычный символ), заменяется строкой ".*"

Тестирование

Я использовал следующее преобразование 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>
...