You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cocoon.apache.org by wh...@mac.com on 2003/07/03 01:14:15 UTC

[ Flow ] JXPath, unnamed element nodes, and nested Beans in XMLForm

I'm directing this question to the developer's list since the people 
deep into flow appear to be here.

I've got a question about XForms/XPath syntax when using xmlForm.js and 
the XMLForm transformer. The problem is how to address 'unnamed' nodes.

I have a bean with a nested structure (employees courtesy of Allan 
Moore):

  	workplan.bean =
  	{
  		firstName: "Campion",
  		lastName: "Bond",
  		email: "cbond@foriegnoffice.gov.uk",
  		tasks :
  		[
  			{
  				title: "Build Widget Prototype",
  				description: "Build prototype of new X41ZQ widget.",
  				actions: "Plan, Build",
  				people:
  				[
  					{
  						firstName: "Captain",
  						lastName: "Nemo",
  						strengths: "Has own submarine",
  						weaknesses: "Wants to destroy the major colonial powers.",
  						leadershipStyle: "delegate"	
  					},
  					{
  						firstName: "Invisible",
  						lastName: "Man",
  						strengths: "Invisible.",
  						weakenesses: "Is a pervert.",
  						leadershipStyle: "support"
  					}
  				]
  			},
  			{
  				title: "Crush Competition",
  				description: "Kill their warriors, drive them before us, and 
listen to the lamentations of the women.",
  				actions: "Disseminate FUD about Competitors",
  				people:
  				[
  					{
  						firstName: "Dr.",
  						lastName: "Jekyl",
  						strengths: "Genius doctor.",
  						weaknesses: "Has evil twin.",
  						leadershipStyle: "delegate"	
  					},
  					{
  						firstName: "Allan",
  						lastName: "Quartermain",
  						strengths: "Heroic.",
  						weakenesses: "Has a bad smack habit.",
  						leadershipStyle: "support"
  					}
  				]
  			} 			
  		]
  	}

So I want to take this bean and populate a form with it:

Getting the the title, description, and actions out of the form are 
straightforward. Applying:

<document xmlns:xf="http://apache.org/cocoon/xmlform/1.0">
   <xf:form id="form-workplanning" view="workplan" action="edit" 
method="POST">
     <xf:caption>Personal Information</xf:caption>
     <error>
       <xf:violations class="error"/>
     </error>
     <xf:textbox ref="/firstName">
       <xf:caption>First Name</xf:caption>
       <xf:violations class="error"/>
     </xf:textbox>
     <xf:textbox ref="/lastName">
       <xf:caption>Last Name</xf:caption>
       <xf:violations class="error"/>
     </xf:textbox>
     <xf:textbox ref="/email">
       <xf:caption>Email</xf:caption>
       <xf:help>Please check this carefully</xf:help>
       <xf:violations class="error"/>
     </xf:textbox>
	<xf:group nodeset="/" id="tasks_group">
		<xf:caption>Tasks</xf:caption>
		<xf:repeat nodeset="/tasks" id="tasks">
			<xf:group nodeset="task" id="task">
				<xf:textbox ref="title" class="info">
					<xf:caption>Task Name</xf:caption>
				</xf:textbox>
				<xf:textbox ref="description" class="info">
					<xf:caption>Description</xf:caption>
				</xf:textbox>
				<xf:textbox ref="actions" class="info">
					<xf:caption>Actions</xf:caption>
				</xf:textbox>
			</xf:group>
		</xf:repeat>
	</xf:group>
   </xf:form>
  </document>

To the bean yields:

  <xf:form id="form-workplanning" view="workplan" action="edit" 
method="POST">
     <xf:caption>Personal Information</xf:caption>
     <error>

     </error>
     <xf:textbox ref="/firstName"><xf:value>Campion</xf:value>
       <xf:caption>First Name</xf:caption>

     </xf:textbox>
     <xf:textbox ref="/lastName"><xf:value>Bond</xf:value>
       <xf:caption>Last Name</xf:caption>

     </xf:textbox>
     <xf:textbox 
ref="/email"><xf:value>cbond@foriegnoffice.gov.uk</xf:value>
       <xf:caption>Email</xf:caption>
       <xf:help>Please check this carefully</xf:help>

     </xf:textbox>
	<xf:group nodeset="/" id="tasks_group">
		<xf:caption>Tasks</xf:caption>
		<xf:repeat nodeset="/tasks" id="tasks"><xf:group ref="/.[@name = 
'tasks'][1]"><xf:group id="task" nodeset="task" 
xmlns:xf="http://apache.org/cocoon/xmlform/1.0">
				<xf:textbox class="info" ref="/.[@name = 
'tasks'][1]/title"><xf:value>Build Widget Prototype</xf:value>
					<xf:caption>Task Name</xf:caption>
				</xf:textbox>
				<xf:textbox class="info" ref="/.[@name = 
'tasks'][1]/description"><xf:value>Build prototype of new X41ZQ 
widget.</xf:value>
					<xf:caption>Description</xf:caption>
				</xf:textbox>
				<xf:group id="people_group" nodeset="./">
					<xf:caption>People Assigned</xf:caption>
					<xf:repeat id="people" nodeset="people"/>
				</xf:group>
				<xf:textbox class="info" ref="/.[@name = 
'tasks'][1]/actions"><xf:value>Plan, Build</xf:value>
					<xf:caption>Actions</xf:caption>
				</xf:textbox>
			</xf:group>
	...

The difficulty is how to iterate over the people in each task in the 
bean, so that the people are grouped with each task. That problem 
arises because task and people nodes aren't explicitly labeled, and I 
don't want to explicitly label them because the goal is to allow 
insertion of deletion of arbitrary people within tasks, and arbitrary 
tasks within the bean.

If I try and write the JXPath statements from analogy, the result 
doesn't work;

		<xf:repeat nodeset="/tasks" id="tasks">
			<xf:group nodeset="task" id="task">
				<xf:textbox ref="title" class="info">
					<xf:caption>Task Name</xf:caption>
				</xf:textbox>
				<xf:textbox ref="description" class="info">
					<xf:caption>Description</xf:caption>
				</xf:textbox>
				<xf:group nodeset="./" id="people_group">
					<xf:caption>People Assigned</xf:caption>
					<xf:repeat nodeset="people" id="people">
						<xf:group nodeset="person" id="person">
							<xf:textbox ref="firstName">
							  <xf:caption>First Name</xf:caption>
							  <xf:violations class="error"/>
							</xf:textbox>
							<xf:textbox ref="lastName">
							  <xf:caption>Last Name</xf:caption>
							  <xf:violations class="error"/>
							</xf:textbox>
							<xf:textbox ref="strengths">
							  <xf:caption>Strengths</xf:caption>
							  <xf:violations class="error"/>
							</xf:textbox>
							<xf:textbox ref="weaknesses">
							  <xf:caption>Weaknesses</xf:caption>
							  <xf:violations class="error"/>
							</xf:textbox>	
							<xf:selectOne ref="leadershipStyle" selectUIType="radio">
								<xf:caption>Needed Leadership Style</xf:caption>
								<xf:item id="support">
								  <xf:caption>Support</xf:caption>
								  <xf:value>support</xf:value>
								</xf:item>
								<xf:item id="delegate">
								  <xf:caption>Delegate</xf:caption>
								  <xf:value>delegate</xf:value>
								</xf:item>
								<xf:item id="coach">
								  <xf:caption>Coach</xf:caption>
								  <xf:value>coach</xf:value>
								</xf:item>
								<xf:item id="direct">
								  <xf:caption>Direct</xf:caption>
								  <xf:value>direct</xf:value>
								</xf:item>
							</xf:selectOne>		
						</xf:group>
					</xf:repeat>
				</xf:group>
				<xf:textbox ref="actions" class="info">
					<xf:caption>Actions</xf:caption>
				</xf:textbox>
			</xf:group>
		</xf:repeat>

Instead I get:

				<xf:group id="people_group" nodeset="./">
					<xf:caption>People Assigned</xf:caption>
					<xf:repeat id="people" nodeset="people"/>
				</xf:group>

My assumption here was that xf:group works like xsl:for-each or 
xsl:call-template, where the currently selected node is the one in 
scope.

Can I buy a clue here?

Thanks.

-- Bill Humphries