實例
首先創建包含實例的基本表單,如清單 1 所示:
清單 1. 基本表單
<Html
XMLns="http://www.w3.org/1999/xHtml"
XMLns:xforms="http://www.w3.org/2002/xforms"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"
xmlns:ev="http://www.w3.org/2001/XML-events"
xmlns:SOAP-ENV="http://schemas.XMLsoap.org/soap/envelope/"
>
<head>
<title>XForms and Web Services</title>
</head>
<body>
<object id="FormsPlayer"
classid="CLSID:4D0ABA11-C5F0-4478-991A-375C4B648F58">
<b>FormsPlayer has not loaded. Please check your installation.</b>
</object>
<?import namespace="xforms" implementation="#FormsPlayer" ?>
<xforms:model id="WeatherService">
<xforms:instance id="weatherInstance" >
<data>
<employees>
<emp id="1">
<name>Nick</name>
<zip>10314</zip>
</emp>
<emp id="2">
<name>Troy</name>
<zip>90210</zip>
</emp>
<emp id="3">
<name>Bob</name>
<zip>34652</zip>
</emp>
</employees>
<soapmessage>
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.XMLsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/1999/XMLSchema">
<SOAP-ENV:Body>
<ns1:getTemp XMLns:ns1="urn:xmethods-Temperature"
SOAP-ENV:encodingStyle=
"http://schemas.XMLsoap.org/soap/encoding/">
<zipcode xsi:type="xsd:string"></zipcode>
</ns1:getTemp>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
</soapmessage>
</data>
</xforms:instance>
</xforms:model>
</body>
</Html>
該實例包括兩個基本部分: employees 數據和包含在 soapmessage 元素中的 SOAP 消息。在發送 SOAP 消息之前,將使用 employees 數據填充表單。為此,需要添加一個 select1 控件表示可供選擇的雇員,如清單 2 所示:
清單 2. 添加一個 select1 菜單
...
</xforms:model>
<xforms:select1 appearance="minimal"
ref="instance('weatherInstance')//zipcode">
<xforms:label>Choose Employee</xforms:label>
<xforms:itemset nodeset="instance('weatherInstance')//emp">
<xforms:label ref="name"/>
<xforms:value ref="zip"/>
</xforms:itemset>
</xforms:select1>
</body>
</Html>
該空間循環遍歷每個 emp 元素,並創建圖 1 所示的下拉菜單。
圖 1: 基本數據控件
因為已經將 select1 元素的 ref 屬性指向 SOAP 消息的 zipcode 元素,所以只需修改下拉菜單,向 Web 服務請求中添加適當的值即可。
在提交之前,需要填充表單的其他部分。
結構化表單
該項目的目標是創建一個表單,提交 SOAP 消息,然後檢索 SOAP 響應並顯示結果。為此,需要添加提交觸發器按鈕和讀取返回數據的能力,如清單 3 所示:
清單 3. 完成表單
...
</data>
</xforms:instance>
</xforms:model>
<xforms:switch id="switch1">
<xforms:case id="requestGUI">
<xforms:select1 appearance="minimal"
ref="instance('weatherInstance')//zipcode">
<xforms:label>Choose Employee</xforms:label>
<xforms:itemset nodeset="instance('weatherInstance')//emp">
<xforms:label ref="name"/>
<xforms:value ref="zip"/>
</xforms:itemset>
</xforms:select1>
<xforms:trigger style="display:block">
<xforms:label>Get sensor ambIEnt temperature</xforms:label>
<xforms:action ev:event="DOMactivate">
<xforms:send submission="getweather" />
<xforms:toggle case="responseGUI" />
</xforms:action>
</xforms:trigger>
</xforms:case>
<xforms:case id="responseGUI">
<xforms:output ref="instance('weatherInstance')//return">
<xforms:label>Employee local temperature:</xforms:label>
</xforms:output>
</xforms:case>
</xforms:switch>
</body>
</Html>
這裡將表單分成兩種情況,因為為控件提供數據的實例在提交前後是不同的。首先來看第一種情況,表單中包括雇員數據控件和 trigger 按鈕。當用戶單擊觸發器時,浏覽器將發送 getweather 提交(後面創建),並切換到 responseGUI 狀態,在新的結構中查找數據。一旦進入 responseGUI 狀態,浏覽器就會顯示 return 元素中的氣溫值。
現在來創建實際的提交元素。
創建提交元素
為了提交表單,需要創建一個 submission 元素。該 submission 元素不但規定了數據發送到何處(通過 action 屬性),還規定了要發送哪些數據,以及如何處理返回的數據。如清單 4 中所示的 submission 元素:
清單 4. 簡單的 submission 元素
<xforms:submission method="text-XML-post"
action="http://services.xmethods.Net:80/soap/servlet/rpcrouter" />
這個元素可以發揮一定的效用,但還不夠完美。與傳統的 Html 表單相同, XForms 客戶,或者本例中的浏覽器,將整個實例發送給 action 中規定的 URL,然後用接收的響應代替整個頁面。但這並不是我們想要的結果。我們希望只發送 soapmessage 元素中的內容,返回響應時只替換實例,而保持表單的其他部分不變。您可以在 submission 元素中完成操作,如清單 5 所示:
清單 5. submission 元素
...
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
</soapmessage>
</data>
</xforms:instance>
<xforms:submission id="getweather" method="text-XML-post"
ref="instance('weatherInstance')//soapmessage/*"
replace="instance"
action="http://services.xmethods.Net:80/soap/servlet/rpcrouter"
/>
</xforms:model>
submission 元素中規定只發送 soapmessage 元素的內容,收到響應時應該只替換實例而不是整個文檔。
注意,雖然提交的只是實例的一部分,但當 Web 服務發回響應時,將替換整個實例,這是個一錘子買賣。為了避免這種情況,通過使用 replace="none" ,可以指定不使用返回的消息替代任何東西,但這僅適用於提交本身很重要而響應不重要的情況。
結束語
XForms 表單允許您創建包含 SOAP 消息的實例,但實例也可以包含其他數據。比如,在該例中,創建的表單在實例中使用其他來源的數據填充實際的 SOAP 消息。為此,您可以創建 submission 元素,指定實例的哪一部分需要發送。也可以使用 submission 元素說明如何處理返回的數據。