XQuery 注释中的奇怪行为
我有一组 XQuery 转换,正在对 Sedna 数据库中存储的文件运行。它们的格式大致如下:
declare namespace ns0 = "http://www.someuri.com/foo.xsd";
declare namespace ns1 = "http://www.someuri.com/bar.xsd";
(:Declare a few functions like the following:)
declare function local:to-xs-boolean(
$string as xs:string?
)
as xs:boolean? {
if (fn:upper-case($string) = 'Y') then
xs:boolean('true')
else
if (fn:upper-case($string) = 'N') then
xs:boolean('false')
(:if it isn't Y or N then attempt a normal cast - this will fail if it
it isn't any of 'true', 'false', 1, or 0 :)
else
if ($string != '') then
xs:boolean($string)
else
()
(:endif:)
(:endif:)
};
(:Omitted several other functions:)
(:Start the main program:)
(: { :)
for $formName in /ns0:formName
return
<ns1:newFormName>
{
let $address := $formName/ns0:Address
return
<NewAddress>{
(:Omitted code and elements unrelated to this question:)
}</NewAddress>
}
(:Omitted code and elements unrelated to this question:)
</ns1:newFormName>
现在这是我的问题。您看到“for”正上方的一行“(: { :)”了吗?它应该是一条注释,但由于某种原因,它对于我的查询的正常功能至关重要。如果我完全删除它(或从注释中删除“{”),我会得到“
SEDNA Message: ERROR XPDY0002
It is a dynamic error if evaluation of an expression relies on some part of the dynamic context that has not been assigned a value.
如果我取消注释它(因此该行只是读取“{”)”,我会得到“
SEDNA Message: ERROR XPST0003
It is a static error if an expression is not a valid instance of the grammar defined in A.1 EBNF.
Details: at (393:1), syntax error, unexpected {
at (798:33), syntax error, unexpected end of file, expecting "," or }
如果我将其都取消注释并添加匹配的“}” 如果我在
SEDNA Message: ERROR XPST0003
It is a static error if an expression is not a valid instance of the grammar defined in A.1 EBNF.
Details: at (393:1), syntax error, unexpected {
该注释中添加其他文本(例如“(:text foo bar baz() blah {:)”),只要我将“{”留在其中,它就会继续工作。
有没有人以前见过这种情况或者知道可能是什么原因造成的?这并不是一个真正的关键问题(我可以确保我的所有转换中都有“(:{:)”),但这确实让我很好奇。所以感谢您的帮助,甚至只是和我一起困惑。
哦,另一个快速说明 - 我不知道它是否有任何区别,但我正在使用 Charles Foster 的 Sedna API (http://www.cfoster.net/sedna/) 从 Java 运行查询
编辑: 这是我刚刚编写的另一个查询,它显示了相同的问题。这对我来说似乎是可重现的,但如果它与语法错误相关,则可能只是我重现了语法错误。我也会保留旧的,这样这个问题的未来观众就不会感到困惑。
declare namespace ns0 = "http://www.someuri.com/InitialSchema.xsd";
declare namespace ns1 = "http://www.someuri.com/FinalSchema.xsd";
declare function local:to-address(
$recipient as xs:string?,
$line1 as xs:string?,
$line2 as xs:string?,
$line3 as xs:string?,
$city as xs:string?,
$provinceOrState as xs:string?,
$country as xs:string?,
$postalOrZIP as xs:string?
)
as element() {
if (fn:upper-case($country) = 'CA' or fn:upper-case($country) = 'US') then
if (fn:upper-case($country) = 'CA') then
<CanadianAddress>
<City>{ $city }</City>
<Country>{ $country }</Country>
<PostalCode>{ $postalOrZIP }</PostalCode>
<Province>{ $provinceOrState }</Province>
<Recipient>{ fn:normalize-space($recipient) }</Recipient>
<StreetAddress>{ $line1 }</StreetAddress>
<StreetAddress>{ $line2 }</StreetAddress>
<StreetAddress>{ $line3 }</StreetAddress>
<StreetAddress/>
</CanadianAddress>
else
<USAddress>
<City>{ $city }</City>
<Country>{ $country }</Country>
<ZipCode>{ $postalOrZIP }</ZipCode>
<State>{ $provinceOrState }</State>
<Recipient>{ fn:normalize-space($recipient) }</Recipient>
<StreetAddress>{ $line1 }</StreetAddress>
<StreetAddress>{ $line2 }</StreetAddress>
<StreetAddress>{ $line3 }</StreetAddress>
</USAddress>
(:endif:)
else
if ($country != '') then
<InternationalAddress>
<City>{ $city }</City>
<Country>{ $country }</Country>
<PostalCode>{ $postalOrZIP }</PostalCode>
<Recipient>{ fn:normalize-space($recipient) }</Recipient>
<StreetAddress>{ $line1 }</StreetAddress>
<StreetAddress>{ $line2 }</StreetAddress>
<StreetAddress>{ $line3 }</StreetAddress>
</InternationalAddress>
else
<CanadianAddress>
<City>{ $city }</City>
<Country>{ $country }</Country>
<PostalCode>{ $postalOrZIP }</PostalCode>
<Province>{ $provinceOrState }</Province>
<Recipient>{ fn:normalize-space($recipient) }</Recipient>
<StreetAddress>{ $line1 }</StreetAddress>
<StreetAddress>{ $line2 }</StreetAddress>
<StreetAddress>{ $line3 }</StreetAddress>
<StreetAddress/>
</CanadianAddress>
(:endif:)
(:endif:)
};
(:{:)
for $addressForm1 in /ns0:AddressForm
let $token := xs:integer(data($addressForm1/ns0:submissionID))
return
<ns1:NewAddressForm>
<SubmissionID>{ data($addressForm1/ns0:submissionID) }</SubmissionID>
{
let $currentAddress := $addressForm1/ns0:currentAddress
return
<NewAddress>{
local:to-address(
concat(
$addressForm1/ns0:fullName/ns0:firstName,
' ',
substring(data($addressForm1/ns0:fullName/ns0:middleName), 1, 1),
' ',
$addressForm1/ns0:fullName/ns0:lastName
),
data($currentAddress/ns0:line1),
data($currentAddress/ns0:line2),
data($currentAddress/ns0:line3),
data($currentAddress/ns0:city),
data($currentAddress/ns0:provinceOrState),
data($currentAddress/ns0:country),
data($currentAddress/ns0:postalOrZipCode)
)
}</NewAddress>
}
</ns1:NewAddressForm>
这是新查询的一些示例数据
<?xml version="1.0"?>
<ns0:AddressForm xmlns:ns0="http://www.someuri.com/InitialSchema.xsd">
<ns0:submissionID>23774</ns0:submissionID>
<ns0:fullName>
<ns0:firstName>First</ns0:firstName>
<ns0:middleName>Middle</ns0:middleName>
<ns0:lastName>Last</ns0:lastName>
</ns0:fullName>
<ns0:currentAddress>
<ns0:line1>Line 1</ns0:line1>
<ns0:line2>Line 2</ns0:line2>
<ns0:line3>Line 3</ns0:line3>
<ns0:city>City</ns0:city>
<ns0:provinceOrState>Province</ns0:provinceOrState>
<ns0:postalOrZipCode>H0H 0H0</ns0:postalOrZipCode>
<ns0:country>CA</ns0:country>
</ns0:currentAddress>
</ns0:AddressForm>
如果这背后是语法错误,有人会好心地向我指出它在哪一行吗?
I have a set of XQuery transformations that I am running on files stored in a Sedna database. They all have roughly the following format:
declare namespace ns0 = "http://www.someuri.com/foo.xsd";
declare namespace ns1 = "http://www.someuri.com/bar.xsd";
(:Declare a few functions like the following:)
declare function local:to-xs-boolean(
$string as xs:string?
)
as xs:boolean? {
if (fn:upper-case($string) = 'Y') then
xs:boolean('true')
else
if (fn:upper-case($string) = 'N') then
xs:boolean('false')
(:if it isn't Y or N then attempt a normal cast - this will fail if it
it isn't any of 'true', 'false', 1, or 0 :)
else
if ($string != '') then
xs:boolean($string)
else
()
(:endif:)
(:endif:)
};
(:Omitted several other functions:)
(:Start the main program:)
(: { :)
for $formName in /ns0:formName
return
<ns1:newFormName>
{
let $address := $formName/ns0:Address
return
<NewAddress>{
(:Omitted code and elements unrelated to this question:)
}</NewAddress>
}
(:Omitted code and elements unrelated to this question:)
</ns1:newFormName>
Now here is my question. You see that line right above the 'for' that reads '(: { :)'? It should be a comment, but for some reason it is crucial to the proper function of my query. If I delete it completely (or remove the '{' from inside the comment) I get
SEDNA Message: ERROR XPDY0002
It is a dynamic error if evaluation of an expression relies on some part of the dynamic context that has not been assigned a value.
If I uncomment it (so the line just reads '{') I get
SEDNA Message: ERROR XPST0003
It is a static error if an expression is not a valid instance of the grammar defined in A.1 EBNF.
Details: at (393:1), syntax error, unexpected {
at (798:33), syntax error, unexpected end of file, expecting "," or }
If I have it both uncommented and add a matching '}' to the end of the file I get
SEDNA Message: ERROR XPST0003
It is a static error if an expression is not a valid instance of the grammar defined in A.1 EBNF.
Details: at (393:1), syntax error, unexpected {
If I add other text to that comment (like '(:text foo bar baz() blah {:)') it will continue to work as long as I leave that '{' in there.
Has anybody ever seen this before or have any idea what might be causing it? It isn't really a crucial issue (I can just make sure I have '(:{:)' in all of my transformations), but it is really making me curious. So thanks for any help, or even just joining me in puzzlement.
Oh one other quick note - I don't know if it makes any difference, but I am running the query out of Java using Charles Foster's Sedna API (http://www.cfoster.net/sedna/)
Edit: Here is a different query that I just wrote which shows the same issue. This seems reproducable to me, but if it is syntax error related it could be just me reproducing the syntax error. I will leave the old one up as well so future viewers of this question aren't confused.
declare namespace ns0 = "http://www.someuri.com/InitialSchema.xsd";
declare namespace ns1 = "http://www.someuri.com/FinalSchema.xsd";
declare function local:to-address(
$recipient as xs:string?,
$line1 as xs:string?,
$line2 as xs:string?,
$line3 as xs:string?,
$city as xs:string?,
$provinceOrState as xs:string?,
$country as xs:string?,
$postalOrZIP as xs:string?
)
as element() {
if (fn:upper-case($country) = 'CA' or fn:upper-case($country) = 'US') then
if (fn:upper-case($country) = 'CA') then
<CanadianAddress>
<City>{ $city }</City>
<Country>{ $country }</Country>
<PostalCode>{ $postalOrZIP }</PostalCode>
<Province>{ $provinceOrState }</Province>
<Recipient>{ fn:normalize-space($recipient) }</Recipient>
<StreetAddress>{ $line1 }</StreetAddress>
<StreetAddress>{ $line2 }</StreetAddress>
<StreetAddress>{ $line3 }</StreetAddress>
<StreetAddress/>
</CanadianAddress>
else
<USAddress>
<City>{ $city }</City>
<Country>{ $country }</Country>
<ZipCode>{ $postalOrZIP }</ZipCode>
<State>{ $provinceOrState }</State>
<Recipient>{ fn:normalize-space($recipient) }</Recipient>
<StreetAddress>{ $line1 }</StreetAddress>
<StreetAddress>{ $line2 }</StreetAddress>
<StreetAddress>{ $line3 }</StreetAddress>
</USAddress>
(:endif:)
else
if ($country != '') then
<InternationalAddress>
<City>{ $city }</City>
<Country>{ $country }</Country>
<PostalCode>{ $postalOrZIP }</PostalCode>
<Recipient>{ fn:normalize-space($recipient) }</Recipient>
<StreetAddress>{ $line1 }</StreetAddress>
<StreetAddress>{ $line2 }</StreetAddress>
<StreetAddress>{ $line3 }</StreetAddress>
</InternationalAddress>
else
<CanadianAddress>
<City>{ $city }</City>
<Country>{ $country }</Country>
<PostalCode>{ $postalOrZIP }</PostalCode>
<Province>{ $provinceOrState }</Province>
<Recipient>{ fn:normalize-space($recipient) }</Recipient>
<StreetAddress>{ $line1 }</StreetAddress>
<StreetAddress>{ $line2 }</StreetAddress>
<StreetAddress>{ $line3 }</StreetAddress>
<StreetAddress/>
</CanadianAddress>
(:endif:)
(:endif:)
};
(:{:)
for $addressForm1 in /ns0:AddressForm
let $token := xs:integer(data($addressForm1/ns0:submissionID))
return
<ns1:NewAddressForm>
<SubmissionID>{ data($addressForm1/ns0:submissionID) }</SubmissionID>
{
let $currentAddress := $addressForm1/ns0:currentAddress
return
<NewAddress>{
local:to-address(
concat(
$addressForm1/ns0:fullName/ns0:firstName,
' ',
substring(data($addressForm1/ns0:fullName/ns0:middleName), 1, 1),
' ',
$addressForm1/ns0:fullName/ns0:lastName
),
data($currentAddress/ns0:line1),
data($currentAddress/ns0:line2),
data($currentAddress/ns0:line3),
data($currentAddress/ns0:city),
data($currentAddress/ns0:provinceOrState),
data($currentAddress/ns0:country),
data($currentAddress/ns0:postalOrZipCode)
)
}</NewAddress>
}
</ns1:NewAddressForm>
And here is some sample data for the new query
<?xml version="1.0"?>
<ns0:AddressForm xmlns:ns0="http://www.someuri.com/InitialSchema.xsd">
<ns0:submissionID>23774</ns0:submissionID>
<ns0:fullName>
<ns0:firstName>First</ns0:firstName>
<ns0:middleName>Middle</ns0:middleName>
<ns0:lastName>Last</ns0:lastName>
</ns0:fullName>
<ns0:currentAddress>
<ns0:line1>Line 1</ns0:line1>
<ns0:line2>Line 2</ns0:line2>
<ns0:line3>Line 3</ns0:line3>
<ns0:city>City</ns0:city>
<ns0:provinceOrState>Province</ns0:provinceOrState>
<ns0:postalOrZipCode>H0H 0H0</ns0:postalOrZipCode>
<ns0:country>CA</ns0:country>
</ns0:currentAddress>
</ns0:AddressForm>
If it is a syntax error that is behind this would someone be so kind as to point out to me which line it is on?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
问题在于以下行:
在 Sedna 中(记住 Sedna 是数据库,而不是 XQuery 处理器),无法定义默认上下文项(请参阅 XQuery 1.0、2.1.2 动态上下文)在查询执行之前。所以它不知道如何评估
./ns0:formName
(相当于简单的/ns0:formName
) - 它只是不知道是什么。
在这种情况下意味着。您应该将要处理的文档加载到数据库中,然后使用 doc() 函数访问它:
据我所知,您也可以尝试 Charles Fosters 的 Sedna XQJ API(无论如何应该比 XML:DB API 更好),它支持定义上下文项。
顺便说一句,如果您对 Sedna 的 XML:DB 或 XQJ 有疑问,最好直接在 sedna 讨论列表中询问他们。查尔斯很有可能会回答你。
The problem is the following line:
In Sedna (remember Sedna is the database, not XQuery processor) there is no way to define default context item (see XQuery 1.0, 2.1.2 Dynamic Context) prior the query execution. So it doesn't know how to evaluate
./ns0:formName
(which equivalent of simple/ns0:formName
) - it just doesn't know what.
means in this case.You should load the document you want to process into the database and then access it with
doc()
function:As far as I know, you may also try Charles Fosters's XQJ API for Sedna (which should be anyway better than XML:DB API) which has support for defining context item.
BTW, if you have questions concerning Sedna's XML:DB or XQJ it's better to ask them directly in sedna-discussion list. There are very good chances that Charles will answer you.