Как отследить дубликаты в списке XML с помощью XQuery? - PullRequest
0 голосов
/ 17 мая 2019

У меня есть следующая структура XML:

<Books>
    <Book>
        <ItemReference>
            <ClassificationCode listID="Name">Book1</ClassificationCode>
            <ClassificationCode listID="Property2"/>
            <ClassificationCode listID="Property3"/>
        </ItemReference>
    </Book>

    <Book>
        <ItemReference>
            <ClassificationCode listID="Name">Book2</ClassificationCode>
            <ClassificationCode listID="Property2"/>
            <ClassificationCode listID="Property3"/>
        </ItemReference>
    </Book>

    <Book>
        <ItemReference>
            <ClassificationCode listID="Name">Book1</ClassificationCode>
            <ClassificationCode listID="Property2"/>
            <ClassificationCode listID="Property3"/>
        </ItemReference>
    </Book>

    <Book>
        <ItemReference>
            <ClassificationCode listID="Name">Book4</ClassificationCode>
            <ClassificationCode listID="Property2"/>
            <ClassificationCode listID="Property3"/>
        </ItemReference>
    </Book>
</Books>

Как правильно сформировать цикл for с использованием XQuery, чтобы создать правило проверки, возвращающее в виде журнала ошибку проверки при обнаружении дубликатов в ClassificationCode[@listID = 'Name']/text(), где /text() = ('Book1', 'Book4')? Это означает, что я не хочу использовать ту же проверку для Book2. Моя проблема в том, что я забочусь о конкретных предметах, если они будут двойными или нет. Чтобы дать более подробную информацию, мой Validation XQuery выглядит следующим образом:

    declare function local:BooksValidation (
    $books as element()*, 

    {

    for $book in $books 
        let $ItemRef := $book/ItemReference

    return (
        if (fn:exists($ItemRef)) then ()
        else 
            local:Issue($error, "No Items found", $currentPath)
            )
    }

    declare function local:Issue (
        $errorCode as xs:string, 
        $message as xs:string, 
        $xpath as xs:string) as xs:string* 
    {   
        concat($errorCode, ': ', $message, ' (XPath : ',  $xpath, ')')
    };

и я хочу включить в этот цикл for точно такой же оператор if, который проверит, есть ли двойные элементы

Ответы [ 2 ]

0 голосов
/ 17 мая 2019

Чтобы идентифицировать дубликаты в XQuery (3 и более поздних версиях), вы используете предложение group by выражения FLOWR для группировки элементов и предложение where, чтобы проверить, обнаружила ли группировка более одного элемента в группе:

declare variable $names as xs:string* external := ('Book1', 'Book4');

for $name in //ClassificationCode[@listID = 'Name'][. = $names]
group by $v := $name
where tail($name)
return 'duplicates for ' || $v

https://xqueryfiddle.liberty -development.net / bFukv8q

С XQuery 1 вы можете использовать

declare variable $names as xs:string* external := ('Book1', 'Book4');

let $names := //ClassificationCode[@listID = 'Name'][. = $names],
    $keys := distinct-values($names)
for $key in $keys
where $names[. = $key][2]
return concat('duplicates for ', $key)

https://xqueryfiddle.liberty -development.net / bFukv8q / 1

0 голосов
/ 17 мая 2019

Используйте запрос ниже для поиска повторяющихся значений элемента:

        let $text :=fn:distinct-values($xml/Book/ItemReference/ClassificationCode[@listID = "Name"]/text())
         for $each in $text
             let $seq := if(count($xml//ClassificationCode[@listID = "Name"]/text()[. = $each]) > 1)
                 then(concat($each, " Values are duplicate"))
                 else()
        return $seq
...