XForms:使用 select 元素获取项目在模型中的位置
XForms: get the position of item in model using select element
我真的很难使用 XForms。这段代码有两个问题。我的刷新操作不起作用,我的 position()
值也不起作用。我找不到任何指定哪些元素 allowed/need 相互嵌套的文档。看起来 XForms 的功能非常强大,但我无法连接任何东西。这只是应该将 "sel" 设置为 2。我也尝试过 "value="instance('foo')/bar[index('ns')]/position()" "因为我不确定是否只有 ref 属性继承上下文节点。
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xf="http://www.w3.org/2002/xforms">
<body>
<xf:model id="master">
<xf:instance xmlns="" id="test">
<foo>
<bar>test</bar>
<bar>error</bar>
<sel>1</sel>
</foo>
</xf:instance>
</xf:model>
<xf:output ref="sel"/>
<xf:select1 id="sl" ref="instance('test')/sel">
<xf:itemset id="ns" nodeset="instance('test')/bar[.='error']">
<xf:label ref="."/>
<xf:value value="./position()"/>
</xf:itemset>
<xf:action>
<xf:refresh model="master"/>
</xf:action>
</xf:select1>
</body>
</html>
任何关于所有 XForms 元素的规则和类别的文献也将不胜感激。 http://www.w3.org/TR/xforms/
确实使它看起来像 select
元素和 trigger
元素是相似的东西。但如果是,为什么我的刷新在 trigger
而不是 select
内工作?
首先,position() 函数根据选定的节点列表求值,在本例中,由于谓词,只有一个元素。可以使用 "count(preceding-sibling::bar)+1".
中的 count() 函数
关于操作,需要一个 ev:event 属性来告知何时执行操作。
关于您的代码的几点说明:
- 通常,XForms 模型放置在 HTML
head
元素下,尽管允许实现将模型放置在其他位置。
- 我看不出您的代码如何将
sel
的值设置为 2
,因为您将拥有一个带有标签 "error" 和值 2
。但是没有代码将 sel
的值设置为 2
。这是因为只有当用户更改下拉列表中的选定值时该值才会更改,但用户不能这样做,因为只有一项。
- 在 XForms 中,您很少需要显式
refresh
操作。数据模型更改完成后,视图会自动刷新。
- 是的,一个
trigger
就像一个select1
:一个core form control。
- 所有 XForms 操作都需要通过
ev:event
属性(或某些实现中的 event
来告知它们对哪个事件做出反应)。您的 action
操作没有 ev:event
属性,所以无论如何也不会有 运行。
- XForms 现在建议始终使用
ref
而不是 nodeset
。一些实现已经支持了。
position()
XPath 表达式有时很棘手,因为它只能在 XPath 上下文位置之后工作。使用 Orbeon,在展示作品时使用 position()
。但如果没有,您也可以尝试使用 count(preceding::bar) + 1
. 来计算位置
以下内容适用于 Orbeon,因为我已将您的项目集指向两个 bar
元素,如果用户更改选择,sel
中的值也会更改。不需要显式操作或刷新,因为下拉列表会在更改时将其值写入 sel
元素。
<html
xmlns="http://www.w3.org/1999/xhtml"
xmlns:ev="http://www.w3.org/2001/xml-events"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xf="http://www.w3.org/2002/xforms">
<head>
<xf:model id="master">
<xf:instance xmlns="" id="test">
<foo>
<bar>test</bar>
<bar>error</bar>
<sel>1</sel>
</foo>
</xf:instance>
</xf:model>
</head>
<body>
<xf:output ref="sel"/>
<xf:select1 id="sl" ref="sel">
<xf:itemset id="ns" nodeset="instance('test')/bar">
<xf:label ref="."/>
<xf:value value="position()"/>
</xf:itemset>
</xf:select1>
</body>
</html>
我真的很难使用 XForms。这段代码有两个问题。我的刷新操作不起作用,我的 position()
值也不起作用。我找不到任何指定哪些元素 allowed/need 相互嵌套的文档。看起来 XForms 的功能非常强大,但我无法连接任何东西。这只是应该将 "sel" 设置为 2。我也尝试过 "value="instance('foo')/bar[index('ns')]/position()" "因为我不确定是否只有 ref 属性继承上下文节点。
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xf="http://www.w3.org/2002/xforms">
<body>
<xf:model id="master">
<xf:instance xmlns="" id="test">
<foo>
<bar>test</bar>
<bar>error</bar>
<sel>1</sel>
</foo>
</xf:instance>
</xf:model>
<xf:output ref="sel"/>
<xf:select1 id="sl" ref="instance('test')/sel">
<xf:itemset id="ns" nodeset="instance('test')/bar[.='error']">
<xf:label ref="."/>
<xf:value value="./position()"/>
</xf:itemset>
<xf:action>
<xf:refresh model="master"/>
</xf:action>
</xf:select1>
</body>
</html>
任何关于所有 XForms 元素的规则和类别的文献也将不胜感激。 http://www.w3.org/TR/xforms/
确实使它看起来像 select
元素和 trigger
元素是相似的东西。但如果是,为什么我的刷新在 trigger
而不是 select
内工作?
首先,position() 函数根据选定的节点列表求值,在本例中,由于谓词,只有一个元素。可以使用 "count(preceding-sibling::bar)+1".
中的 count() 函数关于操作,需要一个 ev:event 属性来告知何时执行操作。
关于您的代码的几点说明:
- 通常,XForms 模型放置在 HTML
head
元素下,尽管允许实现将模型放置在其他位置。 - 我看不出您的代码如何将
sel
的值设置为2
,因为您将拥有一个带有标签 "error" 和值2
。但是没有代码将sel
的值设置为2
。这是因为只有当用户更改下拉列表中的选定值时该值才会更改,但用户不能这样做,因为只有一项。 - 在 XForms 中,您很少需要显式
refresh
操作。数据模型更改完成后,视图会自动刷新。 - 是的,一个
trigger
就像一个select1
:一个core form control。 - 所有 XForms 操作都需要通过
ev:event
属性(或某些实现中的event
来告知它们对哪个事件做出反应)。您的action
操作没有ev:event
属性,所以无论如何也不会有 运行。 - XForms 现在建议始终使用
ref
而不是nodeset
。一些实现已经支持了。 position()
XPath 表达式有时很棘手,因为它只能在 XPath 上下文位置之后工作。使用 Orbeon,在展示作品时使用position()
。但如果没有,您也可以尝试使用count(preceding::bar) + 1
. 来计算位置
以下内容适用于 Orbeon,因为我已将您的项目集指向两个 bar
元素,如果用户更改选择,sel
中的值也会更改。不需要显式操作或刷新,因为下拉列表会在更改时将其值写入 sel
元素。
<html
xmlns="http://www.w3.org/1999/xhtml"
xmlns:ev="http://www.w3.org/2001/xml-events"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xf="http://www.w3.org/2002/xforms">
<head>
<xf:model id="master">
<xf:instance xmlns="" id="test">
<foo>
<bar>test</bar>
<bar>error</bar>
<sel>1</sel>
</foo>
</xf:instance>
</xf:model>
</head>
<body>
<xf:output ref="sel"/>
<xf:select1 id="sl" ref="sel">
<xf:itemset id="ns" nodeset="instance('test')/bar">
<xf:label ref="."/>
<xf:value value="position()"/>
</xf:itemset>
</xf:select1>
</body>
</html>