建立剖析網頁內容的 XML Web Service
今日 Web 展現複雜龐大的內容,然而,大部分的資料都只能靠人眼從瀏覽器來解譯。使用 ASP.NET 建立的 XML Web Service 能夠改善這種情況,提供開發人員 HTML 剖析解決方案剖析遠端傳來的 HTML 網頁,並用程式設計的方式公開結果資料。一旦向網站內容的發行者 (Publisher) 取得許可,並假設內容配置未改變,可接著使用 HTML 剖析公開用戶端所能使用的 XML Web Service。
建置 XML Web Service,採用與建置典型 XML Web Service 不同的模型來剖析網頁內容。剖析的 HTML 網頁的 XML Web Service 是以建立服務描述的方式實作,而服務描述是以 Web 服務描述語言 (WSDL) 撰寫的 XML 文件。服務描述中加入了 XML 項目,以指定輸入參數和資料從剖析的 HTML 網頁傳回。這裡指定資料從剖析的 HTML 網頁傳回,也指定剖析 HTML 內容的指示處,算是完成大部分的實作。開發人員要加入這些 XML 項目來建置剖析 HTML 網頁的 XML Web Service,就必須了解以WSDL 所撰寫的 XML 文件配置。如需 WSDL 的詳細資料,請參閱 W3C 網站 (www.w3.org/TR/wsdl) 的 WSDL 規格。
指定輸出參數
如果剖析的 HTML 網頁接受的參數會影響傳回的 HTML網頁內容,輸入參數便可傳遞給 Web 伺服器。
若要指定輸入參數
到表示指定 <portType> 之 <input> 作業的服務描述,將子 <part> XML 項目加入服務描述中的 <message> XML 項目。
每個 <part> 子項目表示一個參數,且具有兩個屬性:name 和 type。name 屬性為參數名稱,type 屬性則為參數的資料型別。若要定義複雜型別,您可以到 XSD 結構描述內服務描述的 types 區段,然後將複雜型別指定為參數的資料型別。
下列程式碼範例定義三個輸入參數,分別叫做
param1
、param2
和param3
,位在TitlesHttpGet
<portType> 的GetTitlesHttpGetIn
<message> 內。<definitions xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:soapenc="https://schemas.xmlsoap.org/soap/encoding/" targetNamespace="http://tempuri.org/" xmlns="https://schemas.xmlsoap.org/wsdl/" xmlns:myarray="http://tempuri.org/MyArrayType"> <types> <s:schema targetNamespace="http://tempuri.org/MyArrayType"> <s:complexType name="StringArray"> <s:complexContent> <s:restriction xmlns:soapenc="https://schemas.xmlsoap.org/soap/encoding/" base="soapenc:Array"> <s:sequence> <s:element name="String" type="s:string" minOccurs="0" maxOccurs="unbounded" /> </s:sequence> </s:restriction> </s:complexContent> </s:complexType> </s:schema> </types> <message name="GetTitlesHttpGetIn"> <part name="param1" type="s:string"/> <part name="param2" type="s:string"/> <part name="param3" type="myarray:StringArray"/> </message> <portType name="TitlesHttpGet"> <operation name="GetTitles"> <input message="s0:GetTitlesHttpGetIn"/> <output message="s0:GetTitlesHttpGetOut"/> </operation> </portType>
指定資料從剖析的 HTML 網頁傳回
剖析的 HTML 網頁傳回的資料會經過一系列內含規則運算式 (Regular Expression) 的 XML 項目剖析,替每一個資料命名,然後表示在服務描述中。.NET Framework 規則運算式指的是每個 match XML 項目中包含的剖析指示。.NET Framework 規則運算式提供大量的模式比對標記法,可讓您快速地剖析大量文字,找出特定字元模式。如需 .NET Framework 規則運算式語法的詳細資訊,請參閱 .NET Framework 規則運算式。
若要指定從剖析的 HTML 網頁傳回的資料
針對您想要的 <binding>,將符合命名空間的 <text> XML 項目加入 <operation> 項目的 <output> 項目。
針對您想從剖析的 HTML 網頁傳回的每一筆資料,將 <match> XML 項目加入 <text> XML 項目中的服務描述。
屬性 說明 name 類別或屬性名稱表示傳回的資料。如果 <match> XML 項目具有子 <match> 項目,由 Wsdl.exe 工具產生的 Proxy 類別會將 name 屬性與類別產生關聯。子 <match> 項目對應至類別屬性。 pattern 這是用來取得資料的規則運算式模式。如需 .NET Framework 規則運算式語法的詳細資訊,請參閱 .NET Framework 規則運算式。 ignoreCase 指定規則運算式是否要執行區分大小寫,預設為區分大小寫。 repeats 指定應該由規則運算式傳回的數值,以免規則運算式在 HTML 網頁上有多比符合結果。值 1 只傳回第一筆符合結果。值 -1 傳回所有符合結果。規則運算式中,值 -1 等於 *。預設值是 -1。 group 指定相關符合結果的群組。 capture 指定群組中符合結果的索引。 type 透過 Wsdl.exe 產生的 Proxy 類別,會替包含子 <match> 項目的傳回類別 <match>,將使用的型別屬性當作傳回類別的名稱。根據預設,Wsdl.exe 產生的 Proxy 類別會將傳回類別的名稱設定為 name 屬性中指定的名稱。 下列程式碼範例是包含
<TITLE>
和<H1>
標記的簡單網頁範例<HTML> <HEAD> <TITLE>Sample Title</TITLE> </HEAD> <BODY> <H1>Some Heading Text</H1> </BODY> </HTML>
下列程式碼範例是服務描述,會擷取
<TITLE>
和<H1>
標記之間的文字內容,剖析 HTML 網頁的內容。在程式碼範例中,TestHeaders
方法是為GetTitleHttpGet
繫結定義。TestHeaders
方法定義的兩個資料:Title
和H1
,可從 <match> XML 項目中之剖析的 HTML 網頁傳回,能分別剖析<TITLE>
和<H1>
標記的內容。<?xml version="1.0"?> <definitions xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:http="https://schemas.xmlsoap.org/wsdl/http/" xmlns:mime="https://schemas.xmlsoap.org/wsdl/mime/" xmlns:soapenc="https://schemas.xmlsoap.org/soap/encoding/" xmlns:soap="https://schemas.xmlsoap.org/wsdl/soap/" xmlns:s0="http://tempuri.org/" targetNamespace="http://tempuri.org/" xmlns="https://schemas.xmlsoap.org/wsdl/"> <types> <s:schema targetNamespace="http://tempuri.org/" attributeFormDefault="qualified" elementFormDefault="qualified"> <s:element name="TestHeaders"> <s:complexType derivedBy="restriction"/> </s:element> <s:element name="TestHeadersResult"> <s:complexType derivedBy="restriction"> <s:all> <s:element name="result" type="s:string" nullable="true"/> </s:all> </s:complexType> </s:element> <s:element name="string" type="s:string" nullable="true"/> </s:schema> </types> <message name="TestHeadersHttpGetIn"/> <message name="TestHeadersHttpGetOut"> <part name="Body" element="s0:string"/> </message> <portType name="GetTitleHttpGet"> <operation name="TestHeaders"> <input message="s0:TestHeadersHttpGetIn"/> <output message="s0:TestHeadersHttpGetOut"/> </operation> </portType> <binding name="GetTitleHttpGet" type="s0:GetTitleHttpGet"> <http:binding verb="GET"/> <operation name="TestHeaders"> <http:operation location="MatchServer.html"/> <input> <http:urlEncoded/> </input> <output> <text xmlns="https://microsoft.com/wsdl/mime/textMatching/"> <match name='Title' pattern='TITLE>(.*?)<'/> <match name='H1' pattern='H1>(.*?)<'/> </text> </output> </operation> </binding> <service name="GetTitle"> <port name="GetTitleHttpGet" binding="s0:GetTitleHttpGet"> <http:address location="https://localhost" /> </port> </service> </definitions>
下列程式碼範例是前一個服務描述的 Wsdl.exe 所產生的部份 Proxy 類別。
' GetTitle is the name of the proxy class. Public Class GetTitle Inherits HttpGetClientProtocol Public Function TestHeaders() As TestHeadersMatches Return CType(Me.Invoke("TestHeaders", (Me.Url + _ "/MatchServer.html"), New Object(-1) {}),TestHeadersMatches) End Function End Class Public Class TestHeadersMatches Public Title As String Public H1 As String End Class [C#] ' GetTitle is the name of the proxy class. public class GetTitle : HttpGetClientProtocol { public TestHeadersMatches TestHeaders() { return ((TestHeadersMatches)(this.Invoke("TestHeaders", (this.Url + "/MatchServer.html"), new object[0]))); } } public class TestHeadersMatches { public string Title; public string H1; }
請參閱
.NET Framework 規則運算式 | MatchAttribute 類別 | 使用 ASP.NET 建置 XML Web Service