Motivacion editar

A veces se necesita un editor de formato de estructura de datos que son recursivos. En otras palabras: una estructura que se referencia a sí mismo.

Este ejemplo tiene nodos que tienen links. Estos linksretornan al nodo origen. Este es un ejemplo de una estructura de datos auto-referenciada. Esto es común cuando se manipulan graficas. Los sistemas de flujos de trabajo frecuentemente usan estas estructuras.

XML Schema editar

Aquí tenemos una muestra de un XML Schema con un tipo de dato recursivo (un tipo de dato incluye una instancia de sí mismo).

<?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>

Instance Document editar


XForms Example editar

Este ejemplo nos permite ver una grafica de regiones geográficas. Asegúrese decopiar y pegardesdeel punto de vistade edición dellibro de cocinaya que elmayor delos símbolosse convierta.

<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>
= XForms Graph Viewer =
      <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>
=== Current Node ===
      <xf:output ref="instance('path')/current-node-id" class="bold">
         <xf:label>Currnet 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>
=== All Nodes: ===
      <xf:repeat nodeset="//node" id="repeat-node2">
         <xf:output ref="node-id">
            <xf:label>Node Name: </xf:label>
         </xf:output>
      </xf:repeat>
=== Link Types: ===
      <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>

Discussion editar

Muchos de estos es un codigoXformsstraght-forward. Pero hay una línea de código compleja. Esto es cuandose hace clicen un nodoaparece en la listade enlacesy deseahacer que el nodoque acaba de seleccionar seael nodo actual.El truco está en usarla posición ()para que coincida conel valor del índice().Cuando la posicióncoincida con elíndicepuede establecer lacorriente igual-node-id para este nodo.

<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" />