使用XQuery展平XML

时间:2018-08-15 15:06:41

标签: function xquery

我试图将XML层次结构扁平化到文本节点,其中输出标签名称是每个文本节点路径上的连字符连接的标签。我将http://www.chilkatsoft.com/xml-samples/bookstore.xml中提供的示例XML作为输入。

到目前为止,我已经创建了这个XQuery:

declare function local:flatten($prefix as xs:string*, $nodes as node()*) as node()*
{
    for $node in $nodes
    return
        typeswitch($node)
            case element() return
                local:flatten(insert-before($prefix, 1, $node/name()), $node/node())
            case text() return
                element {string-join(fn:reverse($prefix), '-')} {string($node)}
            default return
                'oops'      
}; 

for $b in //bookstore/book return 
    local:flatten((), $b)

这通常有效,但是输出如下:

<?xml version="1.0" encoding="UTF-8"?>
<book>
</book>
<book-title>The Iliad and The Odyssey</book-title>
<book>
</book>
<book-price>12.95</book-price>
<book>
</book>
<book-comments>
</book-comments>
<book-comments-userComment> Best translation I've read. </book-comments-userComment>
<book-comments>
</book-comments>
<book-comments-userComment> I like other versions better. </book-comments-userComment>
<book-comments>
</book-comments>
<book>
</book>
...

我现在不关心缺少根元素(一次只需要一个步骤),但是我不希望正确渲染的文本节点之间出现虚假的空父标签。我究竟做错了什么? 我对XQuery非常陌生,可能犯了一个愚蠢的错误。

1 个答案:

答案 0 :(得分:4)

您的XQuery处理器将<book><title>之类的元素之间的边界空白视为文本节点。要在查询中舍弃这些内容,您需要按如下所示修改typeswitch中的元素大小写:

case text() return
    if (normalize-space($node) eq "") then 
        ()
    else 
        element {string-join(fn:reverse($prefix), '-')} {string($node)}