วันจันทร์ที่ 5 พฤษภาคม พ.ศ. 2551

การแก้ปัญหา XML Parsing Error: xml declaration not at start of external entity

ถ้าหากใช้ไฟล์ JSP เพื่อสร้างไฟล์ XML แล้วพบข้อความดังกล่าวเมื่อใช้เบราว์เซอร์ Firefox

XML Parsing Error: xml declaration not at start of external entity
Line Number 3, Column 1:
^

สาเหตุของปัญหา

XML declaration ไม่ใช่เป็นบรรทัดแรกของไฟล์ XML

แนวทางในการแก้ปัญหา

ลบบรรทัดว่างในไฟล์ XML ก่อนที่จะถึงบรรทัดที่มีส่วนของ XML declaration

วิธีการแก้ปัญหา

1. ในที่นี้สมมุติว่าใช้ Tomcat5 เป็นซอฟต์แวร์ที่รันเซิรฟ์เวอร์ ให้ไปที่ี่ไดเรกทอรี %TOMCAT_HOME%/conf/

2. เข้าไปดูที่ไฟล์ web.xml แล้วหาอิลิเมนต์ servlet ของ jsp เช่น

<servlet>

<servlet-name>jsp</servlet-name>

<servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>

<init-param>

<param-name>fork</param-name>

<param-value>false</param-value>

</init-param>

<init-param>

<param-name>xpoweredBy</param-name>

<param-value>false</param-value>

</init-param>

<load-on-startup>3</load-on-startup>

</servlet>






3. เพิ่ม อิลิมเนต์ เพื่อลบช่องว่างหรือบรรทัดว่างออกไปก่อนในตำแหน่งหลังจากตัวแท็กปิด อันสุดท้าย

<servlet>

<servlet-name>jsp</servlet-name>

<servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>

<init-param>

<param-name>fork</param-name>

<param-value>false</param-value>

</init-param>

<init-param>

<param-name>xpoweredBy</param-name>

<param-value>false</param-value>

</init-param>

<init-param>

<param-name>trimSpaces</param-name>

<param-value>true</param-value>

</init-param>

<load-on-startup>3</load-on-startup>

</servlet>



       


4. ปิดและเปิด Tomcat เซิร์ฟเวอร์ใหม่

อ้างอิง
http://forum.java.sun.com/thread.jspa?threadID=556549&messageID=2728991

วันเสาร์ที่ 26 เมษายน พ.ศ. 2551

การแปลงข้อมูล XML ให้อยู่ในรูปแบบที่ดูง่ายด้วย XSL และ PHP

บ่อยครั้งที่ข้อมูลที่เรามีอยู่ในรูปแบบ XML ซึ่งอาจจะได้มาจากการเรียกใช้เว็บเซอร์วิส หรือรูปแบบมาตรฐานของข้อมูลที่เราได้รับมา แต่เรามักจะพบว่าการอ่านข้อมูล XML นั้นไม่ค่อยง่ายเพราะมีแต่ตัวอักษร และหลายครั้งที่เราต้องการแปลงข้อมูลเหล่าีนี้อยู่ในรูปแบบของเว็บเพจเพื่อแ สดงให้คนอื่นดูด้วย

เราสามารถแปลงข้อมูล XML ให้อยู่ในรูปแบบที่ดูง่ายขึ้นด้วย XSL และ PHP

ตัวอย่างเช่น หากเรามีไฟล์ allResults.xml ที่เราได้รับจากการเรียก Yahoo Search ด้วยคำสำคัญ "Kanda Saikaew" ซึ่งถ้าหากเราดูแล้วจะพบว่ามีข้อมูลที่ซ้อนกันหลายชั้นและดูค่อนข้างจะสลับซับซ้อนดังแสดงในรูป

















ถ้าหากเราต้องการเพียงแ่ค่ชื่อของเว็บเพจและลิงก์ไปที่เว็บเพจนั้นเราก็สามาร ถทำได้โดยการคัดกรองเอาแต่ข้อมูลที่เราต้องการก่อนโดยการเขียนโปรแกรม XML Parser ด้วยภาษา PHP ดังนี้


<?php

$xml = simplexml_load_file('allResults.xml');

$xml_result = "<?xml version='1.0'?><results>";

$xml_result .="<name>Kanda Saikaew</name>";

foreach ($xml->Result as $result) {

$xml_result .= '<result><title>';

$xml_result .= htmlspecialchars($result->Title);

$xml_result .= '</title><url>';

$xml_result .= htmlspecialchars($result->Url);

$xml_result .= '</url></result>';

}

$xml_result .= "</results>";



$fp = fopen('results.xml','w');



$write = fwrite($fp,$xml_result);

fclose($fp);

?>




เราก็จะได้ไฟล์ results.xml



ซึ่งดูง่ายกว่าไฟล์แรกที่เรามี แต่ถ้าหากเราต้องการทำให้เป็นตารางในรูปแบบของเว็บเพจ เราก็จะเขียนไฟล์ results.xsl


<?xml version='1.0'?>

<xsl:stylesheet

xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version='1.0'>

<xsl:output method="html"/>

<xsl:template match="/results">

<html>

<head><title>Search Result by Yahoo</title></head>

<body>

<h1>Search Result for <xsl:value-of select="name"/></h1>

<table border="1">

<tr><th>Title</th><th>Url</th></tr>

<xsl:for-each select="result">

<tr><td><xsl:value-of select="title"/></td>

<td><a href="{url}"><xsl:value-of select="url"/></a></td></tr>

</xsl:for-each>

</table>

</body>

</html>

</xsl:template>

</xsl:stylesheet>






และเขียนโค้ด PHP เพื่ออ่านและแปลงข้อมูลจาก results.xml โดยอาศัยรูปแบบของการแสดงข้อมูลที่ระบุไว้ใน results.xsl ให้เป็น results.html


<?php



$doc = new DOMDocument();

$xsl = new XSLTProcessor();



$xsl_filename = "results.xsl";



$doc->load($xsl_filename);

$xsl->importStyleSheet($doc);



$xml_filename = "results.xml";



$doc->load($xml_filename);

echo $xsl->transformToXML($doc);



?>



แล้วเราก็จะได้ผลลัพธ์ที่ดูง่ายดังแสดงในรูปนี้







วันอาทิตย์ที่ 20 เมษายน พ.ศ. 2551

การใช้ PHP5 เรียกเว็บเซอร์วิสแบบ SOAP

ภาษา PHP เป็นภาษาที่เหมาะสมในการพัฒนาเว็บแอปพลิเคชัน เนื่องจากเป็นภาษาที่ง่าย เรียนรู้ได้เร็ว และสามารถนำมาใช้ได้ฟรี การเรียกใช้เว็บเซอร์วิสด้วยภาษา PHP จึงเป็นที่นิยม ภาษา PHP เวอร์ชันปัจจุบันคือ PHP5 ซึ่งมีความสามารถในการสนับสนุนการเรียกใช้เว็บเซอร์วิสในตัวโดยไม่ต้องดาวน์ โหลดเครื่องมืออะไรเพิ่มเติม ซึ่งจะทำให้ง่ายกว่าการที่ต้องไปดาวน์โหลดเครื่องมืออย่างเช่น NuSOAP ซึ่ง อัปเดตล่าสุดในปี ค.ศ. 2005 อีกทั้งไม่ได้มีกลุ่มผู้ใช้อย่างมากเหมือนกับ SOAP extension ของ PHP5

ใน PHP5 มี SOAP extension ที่ทำให้การเรียกใช้เว็บเซอร์วิสแบบ SOAP ง่ายขึ้นโดยการใช้คลาส SoapClient

ขั้นตอนวิธีการมีดังต่อไปนี้

1) หากเราต้องการเรียกใ้ช้เว็บเซอร์็วิสแบบ SOAP ใดเราก็ต้องรู้ที่อยู่ของเอกสาร WSDL ของเว็บเซอร์วิสนั้นก่อน เช่น

$client = new SoapClient($wsdl);

ถ้าหากว่าพบปัญหา Class 'SoapClient' not found ให้เพิ่มบรรทัดนี้ในไฟล์ php.ini

extension=php_soap.dll

ซึ่งถ้าหากใช้ระบบปฏิบัติการ Windows ไฟล์ php.ini อยู่ที่ไดเรกทอรี c:\windows

2) จากนั้นใช้ฟังก์ชัน _soapCall เพื่อเรียกใช้เมธอดที่เราต้องการโดยที่จะต้องระบุอินพุตพารามิเตอร์ในรูปแบบอาร์เรย์ เช่น

$result = $client->__soapCall($methodName, array($methodArguments));

3) ถ้าหากเราเรียกใช้เว็บเซอร์วิสที่พัฒนาโดยใช้ Microsoft .NET จะต้องมีการระบุ SOAP Action ในอาร์กิวเมนต์ของฟังก์ชัน __soapCall เช่น

$result = $client->__soapCall($methodName, array($methodArguments), array('soapaction' => $soapAction));

4) ถ้าหากเราเรียกใช้เว็บเซอร์วิสที่พัฒนาโดย Microsoft .NET จะได้ผลลัพธ์ที่อยู่ในรูปออปเจตก์ที่ประกอบด้วยอิลิเมนต์ที่มีชื่อตรงกับอิล ิเมนต์เอาต์พุตตามที่ระบุในเอกสาร WSDL เช่น

echo $result->outputElemName;

เราลองมาดูตัวอย่างของการเรียกใช้เว็บเซอร์วิส ปตท (http://www.pttplc.com/pttinfo.asmx) ซึ่งพัฒนาเป็นเว็บเซอร์วิสแบบ SOAP โดยใช้ C#.NET ด้วยโปรแกรมที่เขียนโดยภาษา PHP ดังนี้




<?php

// ที่อยู่ของเอกสาร WSDL ของเว็บเซอร์วิส ปตท");
$wsdl = 'http://www.pttplc.com/pttinfo.asmx?WSDL';

// สร้างออปเจกต์ SoapClient เพื่อเรียกใช้เว็บเซอร์วิส
$client = new SoapClient($wsdl);


// เมธอดที่ต้องการเรียกใช้ CurrentOilPrice
$methodName = 'CurrentOilPrice';



// อินพุตพารามิเตอร์ของเมธอด CurrentOilPrice คือ
// Language ซึ่งเราตั้งค่าให้เป็น TH ถ้าหากต้องการแสดงผลเป็นภาษาไทย
$params = array('Language'=>'TH');

// ระบุค่าของ SOAP Action URI
$soapAction = 'http://www.pttplc.com/ptt_webservice/CurrentOilPrice';

// ใช้ฟังก์ชัน _soapCall ในการเรียกเมธอดที่ระบุ
// ต้องระบุพารามิเตอร์และ SOAP Action
$objectResult = $client->__soapCall($methodName, array('parameters' => $params), array('soapaction' => $soapAction));

// จะต้องดูค่าฟิลด์ที่ชื่อตรงกับชื่อของอิลิเมนต์ที่ระบุใน
// Output Message ซึ่งในที่นี้ก็คือ
// CurrentOilPriceResult
echo $objectResult->CurrentOilPriceResult;
?>



ซึ่งเราก็จะได้ผลลัพธ์ดังรูปที่แสดงต่อไปนี้








อ้างอิงจาก

PHP: SOAP - Manual http://th.php.net/soap

PHP: SoapClient->__soapCall Manual http://th.php.net/soap_soapclient_soapcall


This blog entry was modified from the blog entry by the same author which is at http://gotoknow.org/blog/xmlws/161546

วันพุธที่ 16 เมษายน พ.ศ. 2551

การติดตั้ง WSO2 WSF/PHP บน Windows

ก่อนที่เราจะติดตั้ง WSO2 WSF/PHP เราจะต้องใช้ PHP เวอร์ชัน 5.2.x ขึ้นไป หากต้องการอัปเกรดเวอร์ชัน PHP ควรจะคัดลอกไฟล์ library ซึ่งขึ้นต้นด้วย lib*.dll ของโฟลเดอร์ php ไปไว้ที่โฟลเดอร์ c:\windows\system32 ด้วย

1) ติดตั้งไลบราลี ที่ WSF จะต้องใช้

1.1) ดาวน์โหลด libxml จาก http://www.zlatkovic.com/pub/libxml

จ ากนั้นให้ unzip ไฟล์ที่ดาวน์โหลดมา และให้คัดลอกไฟล์ libxml2.dll ซึ่งอยู่ในไดเรกทอรี bin ให้ไปไว้ที่ไดเรกทอรีี์ที่อยู่ใน PATH environment

1.2) ดาวน์โหลด iconv จาก http://www.zlatkovic.com/pub/libxml/

จากนั้นให้ unzip ไฟล์ที่ดาวน์โหลดมา และให้คัดลอกไฟล์ iconv.dll
ซึ่งอยู่ในไดเรกทอรี์ bin ให้ไปไว้ที่ไดเรกทอรีที่อยู่ใน PATH environment

1.3) extension open_ssl ซึ่งมีอยู่แล้วใน PHP เวอร์ชัน 5.2.x ขึ้นไป

วิธีการติดตั้ง extension ก็ขอให้ดูที่ http://campus.en.kku.ac.th/node/kanda/%E0%B8%81%E0%B8%B2%E0%B8%A3%E0%B8%95%E0%B8%B4%E0%B8%94%E0%B8%95%E0%B8%B1%E0%B9%89%E0%B8%87-php-extension-%E0%B8%9A%E0%B8%99%E0%B8%A3%E0%B8%B0%E0%B8%9A%E0%B8%9A-windows

2) ดาวน์โหลดและติดตั้ง WSF

2.1) ดาวน์โหลดเวอร์ชันไบนารีได้ที่ http://wso2.org/downloads/wsf/php#binary-php
2.2) ทำการ unzip ไฟล์ที่ดาวน์โหลดมาซึ่งเราก็จะได้ไฟล์และไดเรกทอรีที่มีโครงสร้างต่อไปนี้

wso2-wsf-php-bin-1.2.0-win32

| +-- wsf_c

| +-- wsf.dll

| +-- docs

| +-- scripts

| +-- samples

ในที่นี้สมมุติว่าเรา unzip ไฟล์และเปลี่ยนชื่อไดเรกทอรีจาก wso2-wsf-php-bin-1.2.0-win32 เป็น wso-1.2 และเก็บไว้ที่ f:\178375\tools\wso-1.2

2.3) ทำการติดตั้ง extension wsf โดยการคัดลอกไฟล์ wsf.dll ไปไว้ในไดเรกทอรีที่อยู่ใน PATH environment และอยู่ใน c:\php5\ext

และเพิ่มบรรทัด

php_extension=wsf.dll

ในไฟล์ php.ini

นอกจากนี้ต้องเพิ่ม extension xsl โดยการเปลี่ยนจาก

;php_extension=php_xsl.dll

เป็น

php_extension=php_xsl.dll

2.4) ทำการเพิ่มชื่อไดเรกทอรี wso2-wsf-php-bin-1.2.0-win32\wsf_c\lib ไว้ใน PATH environment

2.5) ทำการเพิ่มบรรทัดต่อไปนี้ในไฟล์ php.ini

;wsf

wsf.home="\wsf_c"

wsf.log_path="\wsf_c\logs"

wsf.log_level=3

อย่างเช่นในการทดลองนี้ก็จะเป็น

;wsf

wsf.home="f:\178375\tools\wso-1.2\wsf_c"
wsf.log_path="f:\178375\tools\wso-1.2\wsf_c\logs"
wsf.log_level=3

2.7) ทำการเพิ่มไดเรกทอรีที่ PHP จะค้นหาไฟล์ include ที่เราจะอ้างอิงถึง ซึ่งจะต้องเพิ่มเพื่อทำให้ WSF/PHP สร้างและทำให้เราเห็นไฟล์ WSDL

include_path = ".;f:\178375\tools\wso-1.2\scripts"

2.8) ทำการทดสอบว่าตอนนี้เรามี extension WSF แล้วเหรอยังโดยการสร้างไฟล์ PHP ที่มีโค้ด หากเราติดตั้ง WSF สำเร็จ เราจะเห็นส่วนหนึ่งของผลรันดังรูปที่ 1

wsf extension

อ้างอิงจาก

http://wso2.org/project/wsf/php/1.2.0/docs/manual.html


This article was also posted by the same author at
http://gotoknow.org/blog/xmlws/160231 http://campus.en.kku.ac.th/node/kanda/%E0%B8%81%E0%B8%B2%E0%B8%A3%E0%B8%95%E0%B8%B4%E0%B8%94%E0%B8%95%E0%B8%B1%E0%B9%89%E0%B8%87-wso2-wsfphp-%E0%B8%9A%E0%B8%99-windows