XQuery: как преобразовать строку в правила XPath

#xpath #xquery

#xpath #xquery

Вопрос:

Ниже приведен простой XQuery, который запускает xpath для файла htm и возвращает, сколько совпадающих тегов было найдено. Правила xpath находятся в переменной $rule, но вместо этого я хотел бы использовать строковую переменную $rule-unused . Как я могу преобразовать эту строку в набор узлов и запустить ее для моего документа, аналогичного правилу $document // $ ?

     xquery version "3.1";

    declare namespace persons="http://www.test.com/test/profiles";
    declare variable $uri as xs:string := "/db/apps/Persons/profile.htm";
    declare variable $rule-unused as xs:string := "//persons:relationship";

    let $document := doc($uri)
    let $rule := //persons:relationship
    let $all-lines := $document//$rule
    return
    <test>
        {
            count( $all-lines )
        }
    </test>
  

Комментарии:

1. Не совсем ясно, чего вы хотите достичь, но в целом для динамической оценки путей или запросов в строке требуется собственное расширение, поэтому проверьте документацию вашего процессора XQuery на наличие eval или аналогичной функции. Конечно, простые поиски, подобные тому, который вы показываете, где вы, кажется, просто хотите проверить имя определенного элемента, могут работать, например //*[name() = $name] , (с помощью, например $name := 'persons:relationship' ).

2. Спасибо. По сути, цель состоит в том, чтобы подсчитать, сколько определенных тегов существует в данном файле htm. В этом примере этот XQuery подсчитывает все <persons:relationship> теги в profile.htm . Однако мы хотели бы прочитать это правило XPath из другого XML-файла в строковом формате.

3. Как я уже сказал, посмотрите на собственные расширения вашего процессора XQuery, я думаю, что ни в XQuery 1, ни в XQuery 3 нет чего-то стандартизированного, за исключением того, что в теории (или в случае комбинированных реализаций XSLT и XQuery, таких как Saxon на практике) вы можете использовать fn:transform функцию для запуска таблицы стилей XSLT, используя xsl:evaluate для оценки пути. Но в целом его проприетарные пространства и пространства имен усложняют жизнь, как и во многих случаях.

4. Кроме того, рассмотрите возможность использования функций более высокого порядка вместо динамически создаваемых выражений. Например, let $rule := function($e){boolean($e/self::person)} return count(//*[$rule(.)] .