XForms 条件项集

问题描述 投票:0回答:1

我试图根据数据(包含在实例“i-rec”中)和一系列约束(包含在实例“i-schemaConstraints”中)来限制项目集中的项目。本质上,如果 i-rec 中有一定数量的元素,那么该选项将不再显示在下拉菜单中,这是基于 i-schemaConstraints 实例中的元素。到目前为止,我还没有找到一种方法将它们与 XPath 结合在一起。是否可以?我正在使用 XSLTForms 版本 1.3。

我尝试过以下方法:

<xf:itemset ref="instance('i-schemaConstraints')/*[local-name() = local-name(current())][1]/*:childElements[1]/descendant-or-self::*:element[count(@ident[. = current()/child::*/local-name()]) &lt; instance('i-schemaConstraints')/*[local-name() = local-name(current())][1]/*:childElements[1]//*:element/@maxOccurs]">
    <xf:label ref="@label"/>
    <xf:value ref="@ident"/>
</xf:itemset>

完整的 XForm 代码如下:

<?xml-stylesheet href="xsl/xsltforms.xsl" type="text/xsl"?>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:xf="http://www.w3.org/2002/xforms"
   xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:xi="http://www.w3.org/2001/XInclude"
   xmlns:tei="http://www.tei-c.org/ns/1.0">
   <head>
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
      <title>Bug Demo</title>
      <xf:model xmlns="http://www.w3.org/2002/xforms" id="m-mss">
         <xf:instance id="i-rec">
            <TEI xmlns="http://www.tei-c.org/ns/1.0">
               <titleStmt>
                  <title/>
                  <title/>
                  <title/>
               </titleStmt>
            </TEI>
         </xf:instance>
         <xf:instance id="i-availableElements">
            <TEI xmlns="http://www.tei-c.org/ns/1.0">
               <titleStmt/>
               <title/>
               <author/>
            </TEI>
         </xf:instance>
         <xf:instance id="i-schemaConstraints">
            <TEI xmlns="http://www.tei-c.org/ns/1.0">
               <titleStmt ident="titleStmt" elementName="titleStmt" elementLabel="Title Statment">
                  <childElements>
                     <element ident="title" label="title" minOccurs="1" maxOccurs="2"/>
                     <element ident="author" label="author" minOccurs="0" maxOccurs="2"/>
                  </childElements>
               </titleStmt>
               <title ident="title" elementName="title" elementLabel="Title Element"/>
               <author ident="author" elementName="author" elementLabel="Author Element"/>
            </TEI>
         </xf:instance>
         <xf:instance id="i-insert-elements">
            <TEI xmlns="http://www.tei-c.org/ns/1.0">
               <element/>
            </TEI>
         </xf:instance>
         <xf:bind id="elementRules" nodeset="instance('i-rec')//*:titleStmt/*:title" constraint="count(instance('i-rec')//*:titleStmt/*:title) &lt;= 2"/>
      </xf:model>
   </head>
   <body>
      <h2>Debug restrictions </h2>
      <!-- Main element -->
      <xf:repeat xmlns="http://www.w3.org/2002/xforms" ref="instance('i-rec')//tei:titleStmt"
         id="titleStmtLevel1">
         <div xmlns="http://www.w3.org/1999/xhtml"
            style="margin:12px; padding:12px; border:1px solid #ccc;">
            <!-- Element Label --> TitleStmt 
            <!-- Select1 to add available elements -->
            <xf:select1 xmlns="http://www.w3.org/2002/xforms"
               ref="instance('i-availableElements')/*[local-name() = local-name(current())]">
               <xf:label/>
               <xf:itemset
                  ref="instance('i-schemaConstraints')/*[local-name() = local-name(current())][1]/*:childElements[1]/descendant-or-self::*:element
                  [count(@ident[. = current()/child::*/local-name()]) &lt; instance('i-schemaConstraints')/*[local-name() = local-name(current())][1]/*:childElements[1]//*:element/@maxOccurs]">
                  <xf:label ref="@label"/>
                  <xf:value ref="@ident"/>
               </xf:itemset>
               <xf:action ev:event="xforms-value-changed">
                  <xf:setvalue ref="instance('i-insert-elements')//*:element"
                     value="instance('i-availableElements')/*[local-name() = local-name(current())]"
                  />
               </xf:action>
            </xf:select1>
            <xf:trigger class="btn btn-outline-secondary btn-sm controls add" appearance="full">
               <xf:label><i class="bi bi-plus-circle"></i> Add element </xf:label>
               <xf:insert ev:event="DOMActivate" context="." at="."
                  origin="instance('i-availableElements')/*[local-name() = instance('i-insert-elements')//*:element][1]"
                  position="after"/>
               <xf:setvalue ev:event="DOMActivate" ref="instance('i-insert-elements')//*:element"/>
               <xf:setvalue ev:event="DOMActivate"
                  ref="instance('i-availableElements')/*[local-name() = local-name(current())][instance('i-schemaConstraints')/*[local-name() = local-name(current())]/*:childElements[1]/*:child/*:element]"
               />
            </xf:trigger>
            <div> Element Value: <xf:input xmlns="http://www.w3.org/2002/xforms"
                  ref=".[not(instance('i-schemaConstraints')/*[local-name() = local-name(current())][1]/*:controlledValues) and instance('i-schemaConstraints')/*[local-name() = local-name(current())][1]/*:childElements/*:textNode[@type='input']]">
                  <xf:alert>Error: No more than 2</xf:alert>
               </xf:input>
               <!-- Child elements -->
               <xf:repeat xmlns="http://www.w3.org/2002/xforms"
                  id="additionalGrpRepeatLevel11GrpRepeatLevel1" ref="./*">
                  <div xmlns="http://www.w3.org/1999/xhtml"
                     style="margin:12px; padding:12px; border:1px solid #ccc;">
                     <xf:trigger xmlns="http://www.w3.org/2002/xforms" appearance="minimal" ref="."
                           ><xf:label>x</xf:label>
                        <xf:delete ev:event="DOMActivate" ref="."/>
                     </xf:trigger>
                     <!-- Element Label --> level 2 <xf:output
                        value="instance('i-schemaConstraints')/*[local-name() = local-name(current())][1]/@elementLabel"
                     /> Element Value: <xf:input
                        ref=".[not(instance('i-schemaConstraints')/*[local-name() = local-name(current())][1]/*:controlledValues) and instance('i-schemaConstraints')/*[local-name() = local-name(current())][1]/*:childElements/*:textNode[@type='input']]">
                        <xf:alert>Error: No more than 1 title allowed here</xf:alert>
                     </xf:input>
                  </div>
               </xf:repeat>
            </div>
         </div>
      </xf:repeat>
   </body>
</html>
xpath xforms xsltforms
1个回答
0
投票

您实际上想要转换

childElements
 中的 
i-schemaConstraints

<titleStmt>
  <childElements>
    <element ident="title" label="title" minOccurs="1" maxOccurs="2" />
    <element ident="author" label="author" minOccurs="0" maxOccurs="2" />
  </childElements>
</titleStmt>

进入绑定约束

<xf:bind
  nodeset="instance('i-rec')//titleStmt"
  constraint="count(title) &gt;= 1 and count(title) &lt;= 2" />
<xf:bind
  nodeset="instance('i-rec')//titleStmt"
  constraint="count(author) &gt;= 0 and count(author) &lt;= 2" />

由于这些绑定约束必须在模型的每次更改时进行评估,因此不在运行时动态评估它们,而是在启动 XForms 处理器之前将其转换为

xf:bind
元素once肯定是值得的。 (我假设
i-schemaConstraints
在运行时不会改变。)

以下 XSLT 1.0 转换可应用于 XForms 文档并插入必要的

xf:bind
元素。

<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xf="http://www.w3.org/2002/xforms" version="1.0">
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()" />
    </xsl:copy>
  </xsl:template>
  <xsl:template match="xf:model">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()" />
      <xsl:apply-templates
        select="xf:instance[@id='i-schemaConstraints']//childElements/element"
        mode="bind" />
    </xsl:copy>
  </xsl:template>
  <xsl:template match="element" mode="bind">
    <xf:bind nodeset="instance('i-rec')//{../../@ident}"
      constraint="count({@ident}) &gt;= {@minOccurs} and count({@ident}) &lt;= {@maxOccurs}" />
  </xsl:template>
</xsl:stylesheet>
© www.soinside.com 2019 - 2024. All rights reserved.