跳转到内容

XForms/图形查看器

来自维基教科书,开放的书籍,为开放的世界

有时您需要使用表单编辑递归的数据结构。换句话说:一个引用自身的结构。

此示例具有具有链接的节点。这些链接反过来指向节点。这是一个自引用数据结构的示例。在操作图时,这很常见。工作流系统经常使用这些结构。

[编辑 | 编辑源代码]

图形编辑器

XML模式

[编辑 | 编辑源代码]

这是一个具有递归数据类型的示例 XML 模式(包含自身实例的数据类型)

graph.xsd

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
   <xs:element name="Graph">
      <xs:annotation>
         <xs:documentation>Comment describing your root element</xs:documentation>
      </xs:annotation>
      <xs:complexType>
         <xs:sequence>
            <xs:element name="graph-name">
               <xs:annotation>
                  <xs:documentation>The name of the graph</xs:documentation>
               </xs:annotation>
            </xs:element>
            <xs:element name="graph-description" minOccurs="0"/>
            <xs:element name="node" type="nodeType" minOccurs="0" maxOccurs="unbounded">
               <xs:annotation>
                  <xs:documentation>A node that has zero or more links</xs:documentation>
               </xs:annotation>
            </xs:element>
         </xs:sequence>
      </xs:complexType>
   </xs:element>
   <xs:complexType name="nodeType">
      <xs:annotation>
         <xs:documentation>A node in a graph with 0 to n links</xs:documentation>
      </xs:annotation>
      <xs:sequence>
         <xs:element name="node-id">
            <xs:annotation>
               <xs:documentation>node identifier</xs:documentation>
            </xs:annotation>
         </xs:element>
         <xs:element name="links" type="linkType" minOccurs="0"/>
      </xs:sequence>
   </xs:complexType>
   <xs:complexType name="linkType">
      <xs:annotation>
         <xs:documentation>A link from one node to another.</xs:documentation>
      </xs:annotation>
      <xs:sequence>
         <xs:element name="link-id">
            <xs:annotation>
               <xs:documentation>link identifier</xs:documentation>
            </xs:annotation>
         </xs:element>
         <xs:element name="node" type="nodeType" maxOccurs="unbounded"/>
      </xs:sequence>
   </xs:complexType>
</xs:schema>

实例文档

[编辑 | 编辑源代码]
<Graph>
   <graph-name>USA</graph-name>
   <graph-description>Example of graph with states, counties, cities and neighborhoods.</graph-description>
   <node>
      <node-id>usa</node-id>
      <links>
         <link-id>states-in-the-us</link-id>
         <node>
            <node-id>california</node-id>
         </node>
         <node>
            <node-id>kansas</node-id>
         </node>
         <node>
            <node-id>illinois</node-id>
         </node>
         <node>
            <node-id>iowa</node-id>
         </node>
         <node>
            <node-id>minnesota</node-id>
            <links>
               <link-id>counties-in-minnesota</link-id>
                <node>
                  <node-id>carver</node-id>
               </node>
               <node>
                  <node-id>dakota</node-id>
               </node>
               <node>
                  <node-id>hennepin</node-id>
                  <links>
                     <link-id>cities in hennpin county</link-id>
                     <node>
                        <node-id>bloomington</node-id>
                     </node>
                     <node>
                        <node-id>minneapolis</node-id>
                     </node>
                     <node>
                        <node-id>richfield</node-id>
                     </node>
                     <node>
                        <node-id>st-louis-park</node-id>
                        <links>
                           <link-id>neighborhoods-in-st-louis-park</link-id>
                           <node>
                              <node-id>aquila</node-id>
                           </node>
                           <node>
                              <node-id>cobblecrest</node-id>
                           </node>
                           <node>
                              <node-id>elmwood</node-id>
                           </node>
                        </links>
                        <!-- neighborhoods-in-st-louis-park -->
                     </node>
                  </links>
                  <!-- cities-in-hennepin county -->
               </node>
               <node>
                  <node-id>ramsey</node-id>
                  <links>
                     <link-id>cities in ramsey county</link-id>
                     <node>
                        <node-id>eagan</node-id>
                     </node>
                     <node>
                        <node-id>st-paul</node-id>
                     </node>
                  </links>
               </node>
            </links>
            <!-- counties-in-minnesota -->
         </node>
         <node>
            <node-id>new-york</node-id>
         </node>
      </links>
      <!-- states-in-the-us -->
   </node>
</Graph>

XForms示例

[编辑 | 编辑源代码]

此示例允许您查看地理区域的图形。

请确保从食谱的编辑视图中复制粘贴,因为大于符号会被转换。

<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:xs="http://www.w3.org/2001/XMLSchema">
   <head>
      <title>XForms Graph Viewer</title>
      <style type="text/css">
         body { font-family: Verdana, Helvetica, sans-serif }
         output {font-size: 10pt}
         .bold {font-weight: bold}
         .indent {margin-left: 250px}
      </style>
      <xf:model>
         <xf:instance xmlns="" id="saved-data" src="usa.xml" />
         <xf:instance xmlns="" id="path">
            <data>
               <!-- set initial value to be the root node -->
               <current-node-id>usa</current-node-id>
            </data>
         </xf:instance>
         <xf:bind id="current-node-id" nodeset="instance('path')/current-node-id" />
         <xf:submission id="save-to-file" method="put" action="usa.xml" replace="instance" instance="saved-data" />
      </xf:model>
   </head>
   <body>
      <h1>XForms Graph Viewer</h1>
      <p>Example of viewing arbitrarily deep hierarchies with XForms v0.1</p>
      <xf:input ref="graph-name">
         <xf:label>Graph Name: </xf:label>
      </xf:input>
       <br />
      <xf:textarea ref="graph-description">
         <xf:label>Description: </xf:label>
      </xf:textarea>
      <br />
       <br />
      <xf:input bind="current-node-id" incremental="true">
         <xf:label>Search for node id:</xf:label>
      </xf:input>
      <br />
      <div class="bread-crumbs">
         <p>Sample short-cuts:</p>
         <xf:trigger>
            <xf:label>usa</xf:label>
            <xf:action ev:event="DOMActivate">
               <xf:setvalue bind="current-node-id" value="'usa'" />
            </xf:action>
         </xf:trigger>
      -&gt;
       <xf:trigger>
            <xf:label>minnesota</xf:label>
            <xf:action ev:event="DOMActivate">
               <xf:setvalue bind="current-node-id" value="'minnesota'" />
            </xf:action>
         </xf:trigger>
      -&gt;
       <xf:trigger>
            <xf:label>hennepin</xf:label>
            <xf:action ev:event="DOMActivate">
               <xf:setvalue bind="current-node-id" value="'hennepin'" />
            </xf:action>
         </xf:trigger>
      -&gt;
      <xf:trigger>
            <xf:label>st-louis park</xf:label>
            <xf:action ev:event="DOMActivate">
               <xf:setvalue bind="current-node-id" value="'st-louis-park'" />
            </xf:action>
         </xf:trigger>
      </div>
      <h3>Current Node</h3>
      <xf:output ref="instance('path')/current-node-id" class="bold">
         <xf:label>Current node id: </xf:label>
      </xf:output>
      <br/>
      <xf:output ref="//node[node-id=instance('path')/current-node-id]/links/link-id" class="bold">
         <xf:label>Link type: </xf:label>
      </xf:output>
      <!-- This is the critical line.  Find all the nodes in the graph that have a node-id of the current-node-id -->
      <xf:repeat nodeset="//node[node-id=instance('path')/current-node-id]/links/node" id="repeat-node1">
         <xf:trigger class="indent">
            <xf:label> <!-- the label on the button -->
               <xf:output ref="node-id" />
            </xf:label>
            <xf:action ev:event="DOMActivate">
               <xf:setvalue ref="instance('path')/current-node-id" value="instance('saved-data')//node[node-id=instance('path')/current-node-id]/links/node[position()=index('repeat-node1')]/node-id" />
            </xf:action>
         </xf:trigger>
      </xf:repeat>
      <h3>All Nodes:</h3>
      <xf:repeat nodeset="//node" id="repeat-node2">
         <xf:output ref="node-id">
            <xf:label>Node Name: </xf:label>
         </xf:output>
      </xf:repeat>
      <h3>Link Types:</h3>
      <xf:repeat nodeset="//links" id="repeat-link">
         <xf:output ref="link-id">
            <xf:label>Link Name: </xf:label>
         </xf:output>
      </xf:repeat>
      <xf:submit submission="save-to-file">
         <xf:label>Save graph</xf:label>
      </xf:submit>
   </body>
</html>

大多数代码都是直接的 XForms 代码。但有一行非常棘手。当您单击链接列表中列出的节点时,您希望将刚刚选择的节点设为当前节点。

诀窍是使用 position() 来匹配 index() 值。当位置匹配索引时,您可以将 current-node-id 设置为该节点。

<xf:setvalue ref="instance('path')/current-node-id"
value="instance('saved-data')//node[node-id=instance('path')/current-node-id]/links/node[position()=index('repeat-node1')]/node-id" />

感谢 Fraser 的提示!


下一页: 选择全部 | 上一页: 导航离开时警告
主页: XForms
华夏公益教科书