0

XQueryでTEXTCLASSからTEIへのタイ​​プスイッチを作成しようとしています。それはそれほど難しいプロセスではありませんが、退屈なので、できるだけ多くのことを自動化しようとしています(そして、より長くかかり、長期的にはより多くを学ぶ)。

Oxygen12とExist1.4.1を使用しています。

今、私はtransform-tei.xqを実行します。これは、gen.xqmの関数を使用して便利なダンディトランスフォーマーを作成します。関数「convert-attr-default」(その目的はノードの属性を取得し、それらの名前/値を小文字に変換することになっています)を追加した後、transform-tei.xqはスローします

"E [localhost] XPDY0002:変数'$attr-name'が設定されていません。[58行18列][58行18列]"

理由がわかりません。XQueryは私が自分で教えようとした最初の言語であり、O'Reillyの本は素晴らしいものですが、それでも新しいタイプの学習であるため、かなり単純なものが欠けていると思います。

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

ありがとう!

4

1 に答える 1

0

一見すると、変数$attr-nameはその参照の3行上で定義されているように見えます。ただし、よく見ると、明らかな定義は、構築された要素のリテラル要素の内容にあることがわかりfunctionます。その要素コンテンツ内から、単一の中括弧が参照がある式モードにエスケープします。

したがって、定義は生成されたクエリにあり、参照は生成されたクエリにあります。両方を同じスコープに入れるには、中括弧を適切に配置する必要があります。生成された関数を開く2つの中括弧があることに注意してください。これは、要素コンテンツに表示される1つの中括弧の表記です。

于 2011-06-26T10:14:25.483 に答える