Я пытаюсь создать переключатель типов в XQuery от TEXTCLASS до TEI. Это не очень сложный процесс, но он утомителен, поэтому я стараюсь максимально автоматизировать его (и требую больше времени и больше учусь в долгосрочной перспективе).
Я использую Oxygen 12 и Exist 1.4.1.
Прямо сейчас я запускаю transform-tei.xq, который создает удобный преобразователь денди, используя функции из gen.xqm. После того, как я добавил функцию "convert-attr-default" (целью которой является получение атрибутов узла и преобразование их имен / значений в нижний регистр), transform-tei.xq выдает
"E [localhost] XPDY0002: переменная '$ attr-name' не установлена. [В строке 58, столбец 18] [в строке 58, столбец 18]"
и я не могу определить почему. Я предполагаю, что упускаю что-то довольно простое, поскольку XQuery - первый язык, который я пытался учить сам, и хотя книга О'Рейли великолепна, это все еще новый тип обучения.
xquery version '1.0';
(: Module: transform-tei.xq
Date: 24 06 2011
Desc: Creates a module with functions to perform a basic transform to TEI on a specified xml document.
:)
declare option exist:serialize "method=text media-type=text/text";
import module namespace gen = "http://www.example.com/test/gen" at "xmldb:exist:///db/richmond/test-queries/gen.xqm";
let $doc := doc("/db/richmond/xml-for-typeswitch/wwa0005.0001.005.xml")
let $tags := gen:tags($doc)
let $config :=
<config>
<modulename>text-tei</modulename>
<namespace>http://www.example.com/test/text-tei</namespace>
</config>
return
gen:create-module($tags, $config)
.
xquery version '1.0';
(: Module: gen.xqm
Note: Stolen/modified from http://en.wikibooks.org/wiki/XQuery/Generating_Skeleton_Typeswitch_Transformation_Modules#Generation_Function
Date: 24 06 2011
Desc: Provides functions to generate a list of all tags in a document and dynamically create a module to perform an identity transformation
:)
module namespace gen = "http://www.example.com/test/gen";
declare variable $gen:cr := " ";
declare function gen:tags($docs as node()*) as xs:string * {
for $tag in distinct-values ($docs//*/name(.))
order by $tag
return $tag
};
declare function gen:create-module($tags as xs:string*, $config as element(config) ) as element(module) {
let $modulename := $config/modulename/text()
let $prefix := $config/prefix/text()
let $pre:= concat($modulename,":",$prefix)
let $namespace := ($config/namespace,"http://mysite/module")[1]/text()
return
<module>
module namespace {$modulename} = "{$namespace}";
(: conversion module generated from a set of tags
:)
<function>
declare function {$pre}convert($nodes as node()*) as item()* {{ {$gen:cr}
for $node in $nodes
return
typeswitch ($node)
{for $tag in $tags
return
<s>case element({$tag}) return {$pre}{replace($tag,":","-")}($node)
</s>
}
default return
{$pre}convert-default($node)
}};
</function>
<function>
declare function {$pre}convert-default($node as node()) as item()* {{ {$gen:cr}
$node
}};
</function>
<function>
declare function {$pre}convert-attr-default($attr as attribute()*) as item()* {{ {$gen:cr}
for $upper-attr in $attr
let $attr-name := fn:node-name($upper-attr)
let $attr-val := fn:data($upper-attr)
return
attribute { $attr-name } { $attr-val }
}};
</function>
{for $tag in $tags
return
<function>
declare function {$pre}{replace($tag,":","-")}($node as element({$tag})) as item()* {{ {$gen:cr}
element {lower-case($tag)} {{
{$pre}convert-attr-default($node/@*),
{$pre}convert($node/node())
}}{$gen:cr}
}};
</function>
}
</module>
};
Спасибо!