|
From: Alfredo C. <alf...@gm...> - 2021-07-07 11:42:01
|
Hi All,
thanks for your suggestions.
I moved from Finian approach to manage a somewhat more complex scenario.
With this function:
declare function local:elems($tkns as xs:string*, $pos as xs:integer) {
if ($tkns[$pos]) then
(
if(starts-with($tkns[$pos + 1], '@'))
then (
let $attr:=replace($tkns[$pos + 1],"@",'')
return
element {$tkns[$pos]} {attribute {$attr} {''},
local:elems($tkns, $pos + 2)}
)
else(
element {$tkns[$pos]} {local:elems($tkns, $pos + 1)}
)
)
else ()
};
I can manage this path for elements:
teiHeader/fileDesc/sourceDesc/msDesc/msIdentifier/idno
And this path for attributes:
teiHeader/fileDesc/sourceDesc/msDesc/physDesc/objectDesc/@form
They become:
<teiHeader>
<fileDesc>
<sourceDesc>
<msDesc>
<msIdentifier>
<idno/>
</msIdentifier>
</msDesc>
</sourceDesc>
</fileDesc>
</teiHeader>
and:
<teiHeader>
<fileDesc>
<sourceDesc>
<msDesc>
<physDesc>
<objectDesc form=""/>
</physDesc>
</msDesc>
</sourceDesc>
</fileDesc>
</teiHeader>
I have all the paths in a sequence so i can parse them:
for $path in $tei-paths
let $token:=tokenize($path, '/')
let $result:=local:elems($token, 1)
return
$result
*The problem is that I have to merge all the pieces before storing them in
a file*, the two xml fragments must become something like:
<teiHeader>
<fileDesc>
<sourceDesc>
<msDesc>
<msIdentifier>
<idno/>
</msIdentifier>
<physDesc>
<objectDesc form=""/>
</physDesc>
</msDesc>
</sourceDesc>
</fileDesc>
</teiHeader>
Thanks,
Alfredo
Il giorno mar 6 lug 2021 alle ore 17:29 Joe Wicentowski <jo...@gm...>
ha scritto:
> Hi Alfredo,
>
> It's always fun to see different approaches to the same problem. To add
> one more approach to the mix, this uses XQuery 3.0's fold-right() function
> (which has been available in eXist since v2.2+) and arrow operator
> (available since v3.1.0+):
>
> "teiHeader/fileDesc/titleStmt/title"
> => tokenize("/")
> => fold-right((), function($segment, $results) { element { $segment } {
> $results } })
>
> If you're not familiar with the arrow operator (
> https://www.w3.org/TR/xquery-3/#id-arrow-operator), you can use it to
> pipe the results of an expression into a follow-on function as its first
> parameter.
>
> On the final line, we use the fold-right function (
> https://www.w3.org/TR/xpath-functions-31/#func-fold-right) to take the
> path segments, from right-to-left, and cumulatively build up the element
> structure from innermost to outermost:
>
> title --> <title/>
> titleStmt --> <titleStmt><title/></titleStmt>
> fileDesc --> <fileDesc><titleStmt><title/></titleStmt></fileDesc>
> teiHeader -->
> <teiHeader><fileDesc><titleStmt><title/></titleStmt></fileDesc></teiHeader>
>
> The result:
>
> <teiHeader>
> <fileDesc>
> <titleStmt>
> <title/>
> </titleStmt>
> </fileDesc>
> </teiHeader>
>
> Another use of fold-right and discussion of this function is in my article
> on parsing Roman numerals:
> https://joewiz.org/2021/05/30/converting-roman-numerals-with-xquery-xslt/.
>
> Joe
>
> On Tue, Jul 6, 2021 at 5:26 AM Alfredo Cosco <alf...@gm...>
> wrote:
>
>> Hi all,
>> I'm working on eXist 4.7.
>> I have a string like this:
>> teiHeader/fileDesc/titleStmt/title
>>
>> Is there a way to transform it and store in a node like:
>> <teiHeader>
>> <fileDesc>
>> <titleStmt>
>> <title/>
>> <titleStmt>
>> </fileDesc>
>> </teiHeader>
>>
>> Thanks,
>> Alfredo
>> _______________________________________________
>> Exist-open mailing list
>> Exi...@li...
>> https://lists.sourceforge.net/lists/listinfo/exist-open
>>
>
|