XForms/图形查看器
外观
< XForms
有时您需要使用表单编辑递归的数据结构。换句话说:一个引用自身的结构。
此示例具有具有链接的节点。这些链接反过来指向节点。这是一个自引用数据结构的示例。在操作图时,这很常见。工作流系统经常使用这些结构。
这是一个具有递归数据类型的示例 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>
此示例允许您查看地理区域的图形。
请确保从食谱的编辑视图中复制粘贴,因为大于符号会被转换。
<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>
->
<xf:trigger>
<xf:label>minnesota</xf:label>
<xf:action ev:event="DOMActivate">
<xf:setvalue bind="current-node-id" value="'minnesota'" />
</xf:action>
</xf:trigger>
->
<xf:trigger>
<xf:label>hennepin</xf:label>
<xf:action ev:event="DOMActivate">
<xf:setvalue bind="current-node-id" value="'hennepin'" />
</xf:action>
</xf:trigger>
->
<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 的提示!