Не удается определить, почему переменная не установлена ​​(E: XPDY0002) в импортированном модуле XQuery.

Я пытаюсь создать переключатель типов в 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 := "&#13;";

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>
};

Спасибо!


person MetricMike    schedule 25.06.2011    source источник


Ответы (1)


На первый взгляд кажется, что переменная $attr-name определена тремя строками выше ее ссылки. Однако более пристальный взгляд показывает, что очевидное определение находится в буквальном содержимом элемента сконструированного элемента function. Из содержимого этого элемента одна фигурная скобка переходит в режим выражения, где находится ссылка.

Таким образом, определение содержится в сгенерированном запросе, тогда как ссылка находится в сгенерированном запросе. Необходимо будет правильно выровнять фигурные скобки, чтобы они попали в одну и ту же область. Обратите внимание, что есть две фигурные скобки, открывающие сгенерированную функцию, что означает, что одна фигурная скобка появляется в содержимом элемента.

person Gunther    schedule 26.06.2011