Prepared XForm seems to be cached

Poster Content
nk4um Moderator
Posts: 901
February 7, 2007 18:46One to many only
I''m afraid your problem is a deliberate design limitation of STM.  It is written as a one to many pattern - ie you can apply one xml resource operation to many xpath locations in the target.  You have an infoset that is effectively a discrete set of many document fragments and want to place them as children of one element - ie a many to one pattern.

The reasons for the STM one-to-many design are here

I think the best solution is to use a parameterized XSLT for this type of operation.

P.
Like · Post Reply
nk4um User
Posts: 41
February 7, 2007 14:40Need appropriate xpath for stm replace
I have an XForms document that contains a "xforms:select1" in which I want to generate the "xform:item" dynamically. Here is a snippet from this document:

                  <xhtml:div>
                     <xforms:select1 bind="sql_data_type" selection="closed">
                        <xforms:label>SQL Datatype</xforms:label>
                        <xforms:hint>Select the appropriate sql datatype for this column</xforms:hint>
                        <xforms:alert>8</xforms:alert>
                        <xforms:item id="sql-select" />
                     </xforms:select1>
                  </xhtml:div>


In my "idoc" document, I am attempting to replace the "<xforms:item id=''sql-select'' />" with items generated from a database query. This query creates the following xml:

<nvp xmlns:xforms="http://www.w3.org/2002/xforms" xmlns:xhtml="http://www.w3.org/1999/xhtml">
   <xforms:item>
      <xforms:label>bit</xforms:label>
      <xforms:value>bit</xforms:value>
   </xforms:item>
   <xforms:item>
      <xforms:label>datetime</xforms:label>
      <xforms:value>datetime</xforms:value>
   </xforms:item>
   <xforms:item>
      <xforms:label>decimal</xforms:label>
      <xforms:value>decimal</xforms:value>
   </xforms:item>
   <xforms:item>
      <xforms:label>image</xforms:label>
      <xforms:value>image</xforms:value>
   </xforms:item>
   <xforms:item>
      <xforms:label>int</xforms:label>
      <xforms:value>int</xforms:value>
   </xforms:item>
   <xforms:item>
      <xforms:label>ntext</xforms:label>
      <xforms:value>ntext</xforms:value>
   </xforms:item>
   <xforms:item>
      <xforms:label>nvarchar</xforms:label>
      <xforms:value>nvarchar</xforms:value>
   </xforms:item>
   <xforms:item>
      <xforms:label>sequence</xforms:label>
      <xforms:value>sequence</xforms:value>
   </xforms:item>
   <xforms:item>
      <xforms:label>smallint</xforms:label>
      <xforms:value>smallint</xforms:value>
   </xforms:item>
   <xforms:item>
      <xforms:label>varchar</xforms:label>
      <xforms:value>varchar</xforms:value>
   </xforms:item>
</nvp>


To replace the "<xform:item id=''sql-select'' />" with the "xform:item"''s above, I am using the following "stm:replace":

      <instr>
         <type>stm</type>
         <operand>column.xml</operand>
         <operator>
            <stm:group xmlns:stm="http://1060.org/stm">
               <stm:replace xpath="//xforms:item[@id=''sql-select'']"><stm:param xpath="/nvp" /></stm:replace>
            </stm:group>
         </operator>
         <param>var:myQueryResults</param>
         <target>var:myFile</target>
      </instr>

This, however, is placing the entire xml snippet, including the "nvp", into the XForm. Because of this, the "xforms:select1" is not working properly. So you know, I have tried several xpath strings and none have worked. Here are the ones I have tried:

xpath="/descendant::*"
xpath="/nvp/descendant::*"
xpath="descendant::item"
xpath="descendant::xforms:item"
xpath="/descendant::nvp"


Any insight as to the correct xpath that would strip the "nvp" node leaving only the "xform:item" nodes would be greatly appreciated. I am about out of options and I am beginning to think this may have something to do with namespaces?

Thanks once again,
Kevin
Like · Post Reply
nk4um Moderator
Posts: 901
February 1, 2007 22:20Namespaces = Complexity : Use with care
You found the alternative solution - because you have given a prefix then the XPath is not ambiguous to stm.

FYI some background: The way I implemented STM was to try to eliminate as much of the complexity of namespaces as possible.  Essentially it dynamically builds a map of prefix:uri bindings and then uses this to resolve the xpath to the qname of the elements.  Strictly STM ought to provide a facility to present a default namespace as a parameter - however STM was written primarily as a data-oriented tool rather than doc-oriented.  In data-centric XML use it is quite rare to encounter default nspaces.

Namespaces came out of the document centric view of XML.  They can provide a way of distinguishing two different data-model''s resources in the same document.  In general though I would always advise to only use namespaces where it is absolutely required for the semantics or business logic of the data process.  If it is not necessary then use of namespaces:

1) Adds extra complexity to the data model.
2) Adds long term maintenance cost to the code (cf the complexity of the DOM API with and without the use of namespaces)
3) Adds uneccessary computational overhead which hurts performance. (Our optimized XPath engine, which is used if there are no prefixes or functions, is many many times faster than the formal strict nspace implementations of either Xalan or Saxon).

I always consider a namespace as an expensive luxury and use them if and only if I cannot distinguish information in the document another way.

That said I should add an option to specify a default ns for stm!

Cheers,

Peter
Like · Post Reply
nk4um User
Posts: 41
February 1, 2007 22:06Are namespaces not important?
Instead of removing the default namespace from the component.xml document, I made it "xmlns:xhtml" and renamed all the elements with an "xhtml:" prefix. At that point, I changed the "stm:replace" command to an xpath of "//xhtml:div[@class=''table'']", which worked. I think your way would have been easier, but I have always read that namespaces are important (how, why and when they are important I have not gathered from the books I have read. However, these books have led me to believe that all elements should contain a namespace). Is this an instance where namespaces are not important or is the path I took what you meant by "removing the default namespace"?

Thanks for your quick response. Your customer service is unbelievable!

Kevin
Like · Post Reply
nk4um Moderator
Posts: 901
February 1, 2007 20:00Default Namespace messing with XPath
Hi Kevin,

OK took a look.  Your XHTML is setting the default namespace...

xmlns="http://www.w3.org/1999/xhtml"


Which means the xpath is not ''seeing'' the div element since it has a fully qualified name.  If remove the default namespace declaration then the XPath finds the div block with the @class attribute.

P.
Like · Post Reply
nk4um Moderator
Posts: 901
February 1, 2007 16:09
Thanks, I''ll take a look this evening.  I''m tied up with a phone conference just at the moment.
Like · Post Reply
nk4um User
Posts: 41
February 1, 2007 15:59Yes, the test worked on it's own...
Your test worked fine, so it has to be something I am doing in my code. I really do not expect you to look through all of my code, but if you do have some time in the near future and want a look, here are the three files I use in this process. I will keep plugging away on my end. I am sure it is something simple and that I can find it. Just going to take some time.

Thanks for your support.

Kevin

component.idoc
<idoc>
   <seq>
      <instr>
         <type>copy</type>
         <operand>this:param</operand>
         <target>var:param</target>
      </instr>
      <exception>
         <instr>
            <type>copy</type>
            <operand>
               <nvp />
            </operand>
            <target>var:param</target>
         </instr>
      </exception>
      <if>
         <cond>
            <instr>
               <type>xpatheval</type>
               <operand>var:param</operand>
               <operator>
                  <xpath>/nvp/entry</xpath>
               </operator>
               <target>this:cond</target>
            </instr>
         </cond>
         <then>
            <instr>
               <type>stm</type>
               <operand>
                  <sql />
               </operand>
               <operator>
                  <stm:group xmlns:stm="http://1060.org/stm">
                     <stm:set xpath="/sql"> SELECT * FROM component WHERE name = ''<stm:param xpath="/nvp/entry/text()" />'';</stm:set>
                  </stm:group>
               </operator>
               <param>var:param</param>
               <target>var:sql</target>
            </instr>
            <instr>
               <type>sqlQuery</type>
               <operand>var:sql</operand>
               <target>var:myQueryResults</target>
            </instr>
            <instr>
               <type>stm</type>
               <operand>component.xml</operand>
               <operator>
                  <stm:group xmlns:stm="http://1060.org/stm">
                     <stm:set xpath="//xforms:instance/nvp/name"><stm:param xpath="/results/row/name/text()" /></stm:set>
                     <stm:set xpath="//xforms:instance/nvp/version"><stm:param xpath="/results/row/version/text()" /></stm:set>
                  </stm:group>
               </operator>
               <param>var:myQueryResults</param>
               <target>this:response</target>
            </instr>
            <instr>
               <type>stm</type>
               <operand>
                  <sql />
               </operand>
               <operator>
                  <stm:group xmlns:stm="http://1060.org/stm">
                     <stm:set xpath="/sql"> SELECT * FROM entity WHERE component_name = ''<stm:param xpath="/nvp/entry/text()" />'';</stm:set>
                  </stm:group>
               </operator>
               <param>var:param</param>
               <target>var:sql</target>
            </instr>
            <instr>
               <type>sqlQuery</type>
               <operand>var:sql</operand>
               <target>var:myQueryResults</target>
            </instr>
            <instr>
               <type>xslt</type>
               <operand>var:myQueryResults</operand>
               <operator>style_entities.xsl</operator>
               <target>var:myReplacementTable</target>
            </instr>
            <exception>
               <instr>
                  <type>copy</type>
                  <operand>
                     <div>
                        <div style="margin-top: 20px;">Component Entites</div>
                        <table border="1">
                           <tr bgcolor="#9acd32">
                              <th align="left">Name</th>
                           </tr>
                           <tr>
                              <td >No Entries</td>
                           </tr>
                        </table>
                     </div>
                  </operand>
                  <target>var:myReplacementTable</target>
               </instr>
            </exception>
            <instr>
               <type>stm</type>
               <operand>this:response</operand>
               <param>var:myReplacementTable</param>
               <operator>
                  <stm:group xmlns:stm="http://1060.org/stm">
                     <stm:replace xpath="//div[@class=''table'']">
                        <stm:param />
                     </stm:replace>
                  </stm:group>
               </operator>
               <target>this:response</target>
            </instr>
            <instr>
               <type>cast</type>
               <operand>this:response</operand>
               <operator>
                  <cast>
                     <mimetype>text/xml</mimetype>
                  </cast>
               </operator>
               <target>this:response</target>
            </instr>
         </then>
         <else>
            <instr>
               <type>cast</type>
               <operand>component.xml</operand>
               <operator>
                  <cast>
                     <mimetype>text/xml</mimetype>
                  </cast>
               </operator>
               <target>this:response</target>
            </instr>
         </else>
      </if>
   </seq>
</idoc>


component.xml
<html
   xmlns="http://www.w3.org/1999/xhtml"
   xmlns:xforms="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>Cincom Design Tool</title>
      <style type="text/css">
         table {
            margin-top: 10px;
            margin-bottom: 10px;
         }
         th {
            background-color: #0cf;
         }
         td.button {
            border: 0px;
         }
         td {
            padding-left: 5px;
            padding-right: 5px;
            border: 1px solid black;
         }
         .mybutton {
            font-family: arial,helvetica,sans-serif;
            font-size: 80%;
            font-weight: bold;
            text-align: center;
         }
         .mybutton a {
            display: block;
            width: 100%;
         }
         .mybutton a:link,
         .mybutton a:visited,
         .mybutton a:hover {
            background-color: #dddddd;
            color: #000;
            text-decoration: none;
         }
         .mybutton a:link,
         .mybutton a:visited {
            border-top: 1px solid #cecece;
            border-bottom: 2px solid #4a4a4a;
            border-left: 1px solid #cecece;
            border-right: 2px solid #4a4a4a;
         }
         .mybutton a:hover {
            border-bottom: 1px solid #cecece;
            border-top: 2px solid #4a4a4a;
            border-right: 1px solid #cecece;
            border-left: 2px solid #4a4a4a;
         }
      </style>
      <xforms:model id="first">
         <xforms:instance xmlns="">
            <nvp>
               <name />
               <version />
            </nvp>
         </xforms:instance>
         <xforms:bind id="name-required" nodeset="/nvp/name" type="xs:string" required="true()" />
         <xforms:submission id="componentprocess" method="post" action="component/process" ref="/nvp" />
      </xforms:model>
      <xforms:model id="second">
         <xforms:submission id="componentcancel" method="post" action="component/cancel" />
      </xforms:model>
   </head>
   <body>
      <div style="font-size: 30px; margin-bottom: 10px;">Cincom Design Tool</div>
      <div style="font-size: 20px;">Component</div>
         <xforms:group ref="/nvp" >
            <xforms:input ref="name">
               <xforms:label>Name</xforms:label>
               <xforms:hint>Enter the name of the component</xforms:hint>
            </xforms:input>
            <xforms:input ref="version">
               <xforms:label>Version</xforms:label>
               <xforms:hint>Enter the version of the component</xforms:hint>
            </xforms:input>
            <xforms:submit submission="componentprocess">
               <xforms:label>Save</xforms:label>
            </xforms:submit>
            <xforms:submit submission="componentcancel">
               <xforms:label>Cancel</xforms:label>
            </xforms:submit>
         </xforms:group>
      <div class="table" />
   </body>
</html>


style_entities.xsl
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
   <xsl:output method="xml" />
   <xsl:param name="param" />

   <xsl:template match="/">
      <div><xsl:apply-templates /></div>
   </xsl:template>

   <xsl:template match="null">
      <table>
         <tr>
            <th>Entities</th>
         </tr>
         <tr>
            <td>No Entries</td>
         </tr>
      </table>
   </xsl:template>

   <xsl:template match="results">
      <table>
         <tr>
            <th>Entities</th>
            <th>Actions</th>
         </tr>
         <xsl:for-each select="row">
            <tr>
               <td><xsl:apply-templates select="name" mode="link" /></td>
               <td class="button"><xsl:apply-templates select="name" mode="button" /></td>
            </tr>
         </xsl:for-each>
         <tr>
            <td class="button">
               <div class="mybutton">
                  <a href="entity">Add</a>
               </div>
            </td>
         </tr>
      </table>
   </xsl:template>

   <xsl:template match="name" mode="link">
      <xsl:variable name="component"><xsl:value-of select="." /></xsl:variable>
      <a href="entity?entry={$component}"><xsl:value-of select="." /></a>
   </xsl:template>

   <xsl:template match="name" mode="button">
      <xsl:variable name="component"><xsl:value-of select="." /></xsl:variable>
      <div class="mybutton">
           <a href="entity/delete?entry={$component}">Delete</a>
      </div>
   </xsl:template>

</xsl:stylesheet>
Like · Post Reply
nk4um Moderator
Posts: 901
February 1, 2007 15:37
Should make no difference.  The literal <html> argument I''m using is still passed as a URI reference anyway.  this:response will be fine.

Did the test work on its own?
Like · Post Reply
nk4um User
Posts: 41
February 1, 2007 15:33Your example works fine.
The only difference I see between your example and mine is that my operand is "this:response". You said earlier that I had to pass my "var:myReplacementTable" into STM as a param or else it would not work. This is not true of the operand with the "this:response" variable, or is it?
Like · Post Reply
nk4um Moderator
Posts: 901
February 1, 2007 13:08This stm:replace attribute test works for me.
Hi Kevin,

I had a look into your problem and created a small test idoc...

<idoc>
  <seq>
    <instr>
      <type>stm</type>
      <operand>
        <html xmlns:xforms="test">
          <body>
            <divstyle="font-size: 30px; margin-bottom: 10px;">Cincom Design Tool</div>
            <xforms:groupref="/nvp">
              <xforms:inputref="name">
                <xforms:label>Name</xforms:label>
                <xforms:hint>Enter the name of the component</xforms:hint>
              </xforms:input>
              <xforms:inputref="version">
                <xforms:label>Version</xforms:label>
                <xforms:hint>Enter the version of the component</xforms:hint>
              </xforms:input>
              <xforms:submitsubmission="componentprocess">
                <xforms:label>Save</xforms:label>
              </xforms:submit>
              <xforms:submitsubmission="componentcancel">
                <xforms:label>Cancel</xforms:label>
              </xforms:submit>
            </xforms:group>
            <divclass="table" />
          </body>
        </html>
      </operand>
      <param>
        <divclass="table">This div block has been replaced</div>
      </param>
      <operator>
        <stm:group xmlns:stm="http://1060.org/stm">
          <stm:replacexpath="/html/body/div[@class=''table'']">
            <stm:param />
          </stm:replace>
        </stm:group>
      </operator>
      <target>this:response</target>
    </instr>
  </seq>
</idoc>


The operand contains your test XHTML page, param contains a new div block.  The stm:replace is using @class=''table''.  This works fine for me.  I did find that I had to declare the xmlns:xforms on the html element but I guess you have done that?

You can run this by pasting it into a file called test.idoc in your workbench and running http://localhost:8080/workbench/test.idoc  Can you please let me know if this test works for you and then we can go from there.

Cheers,

P.
Like · Post Reply
nk4um User
Posts: 41
January 31, 2007 13:26I can make that work with the following modification...
I had to change this:

<stm:group xmlns:stm="http://1060.org/stm">
   <stm:replace xpath="/html/body/div[@class=''table'']"><stm:param /></stm:replace>
</stm:group>


to this:

<stm:group xmlns:stm="http://1060.org/stm">
   <stm:replace xpath="/html/body/div[2]"><stm:param /></stm:replace>
</stm:group>


and I can''t figure out why. Here is the body of the xhtml file being processed so you can see.

   <body>

      <div style="font-size: 30px; margin-bottom: 10px;">Cincom Design Tool</div>
         <xforms:group ref="/nvp" >
            <xforms:input ref="name">
               <xforms:label>Name</xforms:label>
               <xforms:hint>Enter the name of the component</xforms:hint>
            </xforms:input>
            <xforms:input ref="version">

               <xforms:label>Version</xforms:label>
               <xforms:hint>Enter the version of the component</xforms:hint>
            </xforms:input>
            <xforms:submit submission="componentprocess">
               <xforms:label>Save</xforms:label>
            </xforms:submit>
            <xforms:submit submission="componentcancel">

               <xforms:label>Cancel</xforms:label>
            </xforms:submit>
         </xforms:group>
      <div class="table" />
   </body>


I tried stupid things like changing the "class" attribute to an "id" attribute, but this had no effect (as I guessed).
Like · Post Reply
nk4um Moderator
Posts: 901
January 31, 2007 12:50STM Parameters are like XSLT's
Try this...

<instr>
  <type>stm</type>
  <operand>var:myPreparedXForm</operand>
  <param>var:myReplacementTable</param>
  <operator>
    <stm:group xmlns:stm="http://1060.org/stm">
      <stm:replacexpath="/html/body/div[@class=''table'']">
        <stm:param />
      </stm:replace>
    </stm:group>
  </operator>
  <target>this:response</target>
</instr>


The stm:group is like and XSLT it is run in the STM engine which is totally seperate from the DPML language runtime - therefore it has no knowledge of the in-scope variables in DPML.  So to provide a paramenter to you have to give stm a <param> argument and then inside the stm:group script you reference the param with an <stm:param> tag.  In the example above the replace operation will paste in the whole of the doc provided from the param argument.  You can also use an xpath attr on the stm:param to select within it. For reference see the STM example guide.
Like · Post Reply
nk4um User
Posts: 41
January 31, 2007 12:39You were correct...
It was simply a typo causing my HTTPRedirect not to work. I also figured out that Mozilla''s XForm has some issue with the "bind" tag and that is why it was not posting.

Now, however, I have a new issue with NetKernel''s STM functionality. Basically, I can not get the XPath syntax for the "stm:replace". Here is the code:

            <instr>
               <type>xslt</type>
               <operand>var:myQueryResults</operand>
               <operator>style_entities.xsl</operator>
               <target>var:myReplacementTable</target>
            </instr>
            <exception>
               <instr>
                  <type>copy</type>
                  <operand>
                     <div>
                        <div id="entity_exception">Component Entites</div>
                        <table border="1">
                           <tr bgcolor="#9acd32">
                              <th align="left">Name</th>
                           </tr>
                           <tr>
                              <td >No Entries</td>
                           </tr>
                        </table>
                     </div>
                  </operand>
                  <target>var:myReplacementTable</target>
               </instr>
            </exception>
            <instr>
               <type>stm</type>
               <operand>var:myPreparedXForm</operand>
               <operator>
                  <stm:group xmlns:stm="http://1060.org/stm">
                     <stm:replace xpath="/html/body/div[@class=''table'']">var:myReplacementTable</stm:set>
                  </stm:group>
               </operator>
               <target>this:response</target>
            </instr>


The document being processed contains a tag of <div class="table"/> and I would like to replace this div with the <div> of the table coming out of the "xslt" processor (or in this particular case the exception of the "xslt" processor). Just so you know, I also tried an XPath of "//div[@class=''table'']".
Like · Post Reply
nk4um Moderator
Posts: 901
January 27, 2007 10:06HTTPRedirect
Wasn''t very awake this morning when I wrote the last post but I now had chance to concentrate and spotted the problem with why you''re not getting a redirect.  In your redirect instr you have:

<type>HTTPredirect</type>

But it should be HTTPRedirect (capital R). See:

http://docs.1060.org/docs/3.1.0/book/developerreference/doc_ura_HTTPRedirect.html

That should fix the first case.  I think I need to see your code to think about your second case in detail.

Cheers,

P
Like · Post Reply
nk4um Moderator
Posts: 901
January 27, 2007 09:00Please post module
Hi Kevin,

The easiest way to help you out is if I can take a look at the code.  Can you post it somewhere or email to me.  My email is: my forum username at this domain.

Cheers,

Peter (pjr)
Like · Post Reply
nk4um User
Posts: 41
January 26, 2007 21:49Along with my last post, I have another XForm issue...
I could not figure out the timing issue I discussed in my last post, so I decided to try the Mozilla (Firefox) XForm plugin. In reading their documentation, I created the following file (stored on my file system) to post a record to my NetKernel Addressbook application.

<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">
   <head>
      <title>XForms Submit Example</title>
    <xf:model>
      <xf:instance xmlns="">
        <nvp>
          <id />
          <firstname>Jeff</firstname>
          <lastname>Morgan</lastname>
          <add1 />
          <add2 />
          <add3 />
          <add4 />
          <region />
          <country />
          <zip />
          <phone1 />
          <phone2 />
          <phone3 />
          <fax />
          <email1 />
          <email2 />
          <email3 />
          <web1 />
          <web2 />
          <notes />
        </nvp>
      </xf:instance>
         <xf:submission id="save" method="post" action="http://127.0.0.1:8080/my_second_xform/process" ref="/nvp" replace="all" />
    </xf:model>
   </head>
   <body>
       <xf:submit submission="save">
         <xf:label>Save</xf:label>
      </xf:submit>
   </body>
</html>


This worked and added "Jeff Morgan" to my database (created an external reference to the "xform_process.idoc" called "process"). The only thing it did not do is follow the "HTTPredirect" back to my "index.idoc" (mapped to root).

    <instr>
      <type>HTTPredirect</type>
      <operand>
        <uri>/my_second_xform/</uri>
      </operand>
      <target>this:response</target>
    </instr>


Since this much was working, I decided to load the previous XForm into my resource directory and use the following external map to present the form to the user.

<link>
   <name>xform</name>
   <ext>/xform</ext>
   <int>ffcpl:/resources/xform.xml</int>
</link>


So, now when they go to "http://localhost:8080/my_second_xform/xform" they get the same file that was working on my filesystem. However, when I click this pages "submit" button, it does not add an address to the database or get redirected to the "/my_second_xform/" resource.

Would you have any clues as to why this page does not add data to my database from within NetKernel and does not get redirected in either case?
Like · Post Reply
nk4um User
Posts: 41
January 25, 2007 19:27I am missing something with the xform implementation...
In the standard addressbook tutorial, the lines to delete the XForm are at the end of the "xform_process.idoc", and as long as I only use the "submit" button, the application works fine. However, if I place the same delete code at the beginning of the "xform_execute.idoc" all appears fine until you click on "submit". When "submit" is clicked, either the form fails to validate or to process through "xform_process.idoc" (screen refreshes and I am returned to the xform, which has now been cleared of any prior content). Why would it matter wheter I delete the XForm at the end of "xform_process.idoc" or the beginning of "xform_execute.idoc"?
Like · Post Reply
nk4um Moderator
Posts: 901
January 25, 2007 16:12No problem

I will try to determine how I want to proceed on the XForms issue. I have a version of XForms working on IE with Formsplayer and I am guessing I can use that instead of the Chiba implementation if I can''t figure out my timing issue.


XForms is now supported in Firefox 2 I think.  Client-side XForms execution talking back to a server-side XForm generator and data processing services is nice.  Also in vogue is AJAX - this can be very nice too, since it allows for very rapid interactivity and semantic validation (that user name is taken). Something that is completely missing from the XForms model.   Which direction you take depends to some extent on the type of application.


So, are you the creator of the NetKernel software? Really like the resource oriented architecture of the product, althought I am having some trouble getting my mind around how "resource oriented programming" changes the developers view of the world (I come from an object oriented desktop application background and still trying to pick up on the web application concepts). With the advent of XForms and XML Databases, it seems to me that the complexity of many architectures could be greatly simplified with an architecture like that of NetKernel processing all XML using REST (don'' know if this makes since, but it is my current view with the limited knowledge I have :).


Yes I''m one of the creators of NetKernel.  Thanks for the kind words on your first experiences!  Coming from OO world NK can seem very different.  In fact the OO world is still there - its inside the service implementations - the trick to learning to take advantage of NK is to think in terms of resource composition.  In a sense to any applicaiton there is only information or transformation - NK makes lifts this to the front and says thats whats important to think about.  NK makes sure the plumbing takes care of itself.

Let us know how you go on.  If you need any more help just ask.

Cheers,

Peter
Like · Post Reply
nk4um User
Posts: 41
January 25, 2007 15:56Thanks for all your help!
I will try to determine how I want to proceed on the XForms issue. I have a version of XForms working on IE with Formsplayer and I am guessing I can use that instead of the Chiba implementation if I can''t figure out my timing issue.

So, are you the creator of the NetKernel software? Really like the resource oriented architecture of the product, althought I am having some trouble getting my mind around how "resource oriented programming" changes the developers view of the world (I come from an object oriented desktop application background and still trying to pick up on the web application concepts). With the advent of XForms and XML Databases, it seems to me that the complexity of many architectures could be greatly simplified with an architecture like that of NetKernel processing all XML using REST (don'' know if this makes since, but it is my current view with the limited knowledge I have :).

Anyway, thanks again.

Kevin
Like · Post Reply
nk4um Moderator
Posts: 901
January 25, 2007 14:34Java/Windows Sockets
This is a problem with Windows sockets.  Java has exited but the socket is still blocked.  On linux you can use ''netstat'' to see which process is blocking a socket - not sure what is available on windows to provide this info.

Quickest fix is a reboot!

P.
Like · Post Reply
nk4um User
Posts: 41
January 25, 2007 14:31Re: Today the 1060 SocketListener will not start...
Forgot to post the error with the previous posting. Here it is:

Jan 25, 2007 9:28:47 AM org.mortbay.util.ThreadedServer start
WARNING: Failed to start: SocketListener1@0.0.0.0:1060
SEVERE <ex>
    <id>com.ten60.netkernel.util.NetKernelException</id>
    <message>transport refresh had problems</message>
    <stack>
        <level>com.ten60.netkernel.transport.TransportManager.refresh() line:227</level>
        <level>com.ten60.netkernel.transport.TransportManager.start() line:144</level>
        <level>com.ten60.netkernel.container.Container.startComponent() line:336</level>
        <level>com.ten60.netkernel.container.Container.startComponents() line:289</level>
    </stack>
    <ex>
        <id>com.ten60.netkernel.util.NetKernelException</id>
        <message>Failed to start Jetty Transport</message>
        <stack>
            <level>org.ten60.transport.jetty.JettyTransport.addServers() line:118</level>
            <level>org.ten60.transport.jetty.JettyTransport.initialise() line:131</level>
            <level>com.ten60.netkernel.transport.TransportManager.refresh() line:220</level>
            <level>com.ten60.netkernel.transport.TransportManager.start() line:144</level>
        </stack>
        <ex>
            <id>Jetty Server failed to start</id>
            <message>on port 1060</message>
            <stack>
                <level>org.ten60.transport.jetty.JettyTransport.addServers() line:108</level>
                <level>org.ten60.transport.jetty.JettyTransport.initialise() line:131</level>
                <level>com.ten60.netkernel.transport.TransportManager.refresh() line:220</level>
                <level>com.ten60.netkernel.transport.TransportManager.start() line:144</level>
            </stack>
            <ex>
                <id>java.net.BindException</id>
                <message>Address already in use: JVM_Bind</message>
                <stack>
                    <level>java.net.PlainSocketImpl.socketBind()</level>
                    <level>java.net.PlainSocketImpl.bind()</level>
                    <level>java.net.ServerSocket.bind()</level>
                    <level>java.net.ServerSocket.&lt;init&gt;()</level>
                </stack>
            </ex>
        </ex>
    </ex>
</ex>
in com.ten60.netkernel.transport.TransportManager
Like · Post Reply
nk4um User
Posts: 41
January 25, 2007 14:23Today the 1060 SocketListener will not start...
For the past several days, I have run the "startup.bat" file from the command line with no problems. Today when I run this batch file I get a message "Failed to start SocketListener1@0.0.0.0:1060" and can not get to "http://localhost:1060/". Is it possible that I corrupted something?
Like · Post Reply
nk4um Moderator
Posts: 901
January 25, 2007 13:59
As it is currently implemented there is one XForm per session.  It located in the session address space with active URI:  session:[SESSION-GUID]+key@xform.

It would be relatively simple to extend to support any number of XForms in the session which would then require the addition of another argument to active:xform to tell it which XForm in the session to process.

P.
Like · Post Reply
nk4um User
Posts: 41
January 25, 2007 13:47Can only one XForm object exist in a session at any point in time?
Is it one XForm per session or one instance of each XForm you have in your application per session or none of the above?
Like · Post Reply
nk4um Moderator
Posts: 901
January 25, 2007 10:50Accessing the XForm Instance Data
Unfortunately there is no way to access the instance data from the XForm in the Chiba API.  The XForm resource stored in the session is actually a Chiba XForm object - this gets passed to the XForm engine each time and the XML is then styled in the engine using the supplied (or default) XSLT.  One solution is that you could supply an alternate XSLT that would output the instance data from the form instead of rendering it to XHTML?  You can find the default XSLT in the chiba module below the com.chiba. packages.

If you''re getting really stuck then please post your module somewhere and I''ll take a look. This would make talking over the options a bit easier.

Peter
Like · Post Reply
nk4um User
Posts: 41
January 24, 2007 21:09New problem with "deleteXForm" timing (can ignore last post)
Before I delete the "old" XForm and create a new one, is there a way to obtain the values stored in the fields of the "old" XForm? If the user uses the browsers back-arrow button instead of clicking the "submit" or "cancel" button on the "Add/Edit entry" page, the XForm will continue to contain the values of the entry they were working on when the press the back-arrow (at least until the click "submit" or "cancel" on that page). To avoid this, I was wanting to put code into the "xform-execute.idoc" to see if the "id" parameter passed to the XForm matched the "id" field of the "old" XForm. If it doesn''t, I would then delete that XForm and recreate it with "XForm instr" command passing the "this:param:session" (I believe this would recreate the XForm in the same session but with new values?).
Like · Post Reply
nk4um User
Posts: 41
January 24, 2007 18:32Now the XForm initializes, but will not process
When I delete the "old" XForm, does a new one get created with the "XForm instr" in the same session with the following "code":

        <instr>
          <type>buildSessionResourceURI</type>
          <operand>this:param:session</operand>
          <operator>
            <key>xform</key>
          </operator>
          <target>var:xformSession</target>
        </instr>
        <instr>
          <type>delete</type>
          <operand>curi:var:xformSession</operand>
        </instr>
        <instr>
          <type>XForm</type>
          <xform>xform.xml</xform>
          <xslt>xform_style.xsl</xslt>
          <param>var:param</param>
          <session>this:param:session</session>
          <target>var:myExecutedXForm</target>
        </instr>


When I click the "submit" button to process the XForm with the "xform-process.idoc", the screen basically refreshes and erases any content that was typed into the fields. My guess is that the processor believes the field values are "null" and thereby keeps the "lastname required" rule from allowing the form to process through the "form-process.idoc". However, when I remove the "lastname" constraint, the form will not even initialize (i.e. no fields or labels are displayed), which I find odd.
Like · Post Reply
nk4um Moderator
Posts: 901
January 24, 2007 15:30Working
Good thinking!  Yes this is the detailed implementation of how to create the URI to the XForm resource in the session and then explicitly delete it. [I thought that he destroyXForm script did this too but its old and undocumented! Will take a look at it.]

Glad it working for you.

Peter
Like · Post Reply
nk4um User
Posts: 41
I proceed to place the code you supplied right before the "stm instr" that prepares the "new" XForm. It did not seem to do anything (even tried a cold restart). However, this did get me thinking that I had seen something similar to this in the "xform_process.idoc". Therefore, I stole the following code from there, and it worked. However, I want to make sure this code basically does what you discussed (i.e. is the following code equivilant to the code you supplied)?


    <instr>
      <type>buildSessionResourceURI</type>
      <operand>this:param:session</operand>
      <operator>
        <key>xform</key>
      </operator>
      <target>var:xformSession</target>
    </instr>
    <instr>
      <type>delete</type>
      <operand>curi:var:xformSession</operand>
    </instr>
Like · Post Reply
nk4um Moderator
Posts: 901
January 24, 2007 14:50The Problem of Stateful Serverside XForms
Hi,

You''ve come across one of the niggles with serverside XForms.  The XForm spec was really designed with a client side model in mind.  However browser support has been slow coming (probably due to ambivalence in the IE camp!).  Chiba and other XForms engines are really temporary solutions that do there best to transpose XForms over to the serverside.

However XForms is a stateful processing model and is not something that can be done with a RESTful client-server pattern.  Therefore the XForms engines requires sessions and stateful mapping to and from these sessions.

Your problem is not NetKernel caching per-se, rather the XForms engine is using the stateful XForm in the current session (sessions are resource address spaces in NK).  To get it to use the newly supplied one you first need to flush the existing XForm from the session. You can use: active:destroyXForm like this...

<instr>
  <type>destroyXForm</type>
  <session>this:param:session</session>
</instr>


Of course you must now make sure that you only clean up the xform from the session prior to executing the new XForm instance  for the first time. Since during the execution phase, the XForm will keep phoning home for updates until all its conditions are satisfied.

Hope this helps.

Peter
Like · Post Reply
nk4um User
Posts: 41
January 24, 2007 14:32Prepared XForm seems to be cached
I am attempting to extend the "AddressBook" tutorial to learn more about the functioning of XForms within NetKernel. I general, I am wanting to extend the "xform-execute.idoc" to except a parameter to an already existing address entry and fill the XForm with that information. Problem I am having is that it works the first time, but when I select any other address entry to edit, the XForm comes up with the original contents (i.e. the information from the first entry selected). Does this problem have something to do with caching? I tried to "expire" my variables and this had no effect.

Here is the snippet from my "xform-execute.idoc" that I believe should replace XForm field values based on the value of the "entry" variable passed (currently only providing a value for the lastname field):

    <instr>
      <type>stm</type>
      <operand>
        <sql />
      </operand>
      <operator>
        <stm:group xmlns:stm="http://1060.org/stm">
          <stm:set xpath="/sql"> SELECT * FROM entries WHERE id = <stm:param xpath="/nvp/entry/text()" />;
          </stm:set>
        </stm:group>
      </operator>
      <param>this:param</param>
      <target>var:sql</target>
    </instr>
    <instr>
      <type>sqlQuery</type>
      <operand>var:sql</operand>
      <target>var:queryResults</target>
    </instr>
    <instr>
      <type>stm</type>
      <operand>xform.xml</operand>
      <operator>
        <stm:group xmlns:stm="http://1060.org/stm">
          <stm:set xpath="//xforms:instance/nvp/lastname"><stm:param xpath="/results/row/lastname/text()" /></stm:set>
        </stm:group>
      </operator>
      <param>var:queryResults</param>
      <target>var:myPreparedXForm</target>
    </instr>
    <instr>
      <type>XForm</type>
      <xform>var:myPreparedXForm</xform>
      <xslt>xform_style.xsl</xslt>
      <param>var:param</param>
      <session>this:param:session</session>
      <target>this:response</target>
    </instr>

Any help would be greatly appreciated.
Like · Post Reply