410 likes | 519 Views
Web-based Programming Lanjut Pertemuan 10. Matakuliah : M0492 / Web-based Programming Lanjut Tahun : 2007. XML and ADO. ADO Recordsets Stored as XML ADO Recordset Namespace ADO Recordset Schema Data Islands and Binding Saving Recordsets as XML Opening Recordsets
E N D
Web-based Programming Lanjut Pertemuan 10 Matakuliah : M0492 / Web-based Programming Lanjut Tahun : 2007
XML and ADO • ADO Recordsets Stored as XML • ADO Recordset Namespace • ADO Recordset Schema • Data Islands and Binding • Saving Recordsets as XML • Opening Recordsets • Extensible Styling Language (XSL)
ADO Recordsets Stored as XML • The first thing is how ADO presents its data as XML. • This is the only way XML can be extracted from ADO at the moment. • We have an element for each row in the table, and the fields are attributes of the row element. • This way of defining data using attributes for each data item means that some of that repetition is reduced <z:row au_id=“172-32-1176” au_lname=“White” au_fname=“Johnson” /> <z:row au_id=“213-46-8915” au_lname=“Green” au_fname=“Marjorie” />
ADO Recordset Namespace • If using ADO to send and retrieve XML data then there will be a schema associated with the XML data file. • The schema is embedded into the XML, at the top of document. <xml xmlns:s= “uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882” xmlns:dt= “uuid:C2F41010-65B3-11d1-A29F-00AA00C14882” xmlns:rs= “urn:schemas-microsoft-com:rowset” xmlns:z= “#RowsetSchema”>
ADO Recordset Namespace Using namespaces ensures that the element names chosen by Microsoft are applied to the correct schema.
ADO Recordset Schema • The Row Element • Element that identifies schema: • The definition of an element by ElementType <s:Schema id=“RowsetSchema”> <s:ElementType name=“row” content=“eltOnly”>
ADO Recordset Schema • A row element that can only contain other elements. • This is essentially an empty tag, but for the schema, empty means no content at all, including attributes. <z:row au_id=“172-32-1176” au_lname=“White” au_fname=“Johnson” phone =“408 496-7223” address=“10932 Bigge Rd.” city=“Menlo Park” state=“CA” zip=“94025” contract=“True” />
ADO Recordset Schema • The Field Attributes • At the XML data, the field values are represented as attributes. • Schema must define attributes. • First, the definition of the attribute itself • Second, the definition of the data type for the attribute. • Define an attribute • define what it will be called – this should map to the field name of the data. • define 2 other attributes : • First, a unique number for each attribute – this is the first attribute, the remaining attributes are sequentially numbered. • The other attribute is “writeunknown” which identifies whether the attribute can be updated
ADO Recordset Schema • Data Types • When generating XML from ADO, the data types are automatically created. <s:AttributeType name=“au_id” rs:number=“1” rs:writeunknown=“true” > AttributeType also has a child element to define the data type of the attribute: <s:datatype dt:type=“string” dt:maxLength=“11” rs:maybenull=“false” />
ADO Recordset Schema The table below lists the data type supported by the XML-data schema
ADO Recordset Schema The W3C also allow a set of primitive types
Data Islands and Binding • Create a data island with the <XML> tag in an HTML page This reference an external XML file as the source of the data. Alternatively you can embed the XML data within the <XML> tag. <XML ID=“dsoData” SRC=“authors.xml”></XML> <XML ID=“dsoData”> <Authors> <Author> <au_id>172-32-1176</au_id> <au_lname>White</au_lname> <au_fname>Johnson</au_fname> </Author> <Authors> </XML>
Data Islands and Binding • Binding can take two forms • First, bind a single elements • Second, use table binding <INPUT TYPE=“TEXT” DATASRC=“#dsoData” DATAFLD=“au_id”></INPUT> <TABLE DATASRC =“#dsoData”> <TR> <TD> <INPUT TYPE=“TEXT” DATAFLD=“au_id”></INPUT></TD> <TD> <INPUT TYPE=“TEXT” DATAFLD=“au_fname”></INPUT></TD> </TR> </TABLE>
Data Islands and Binding • Binding Hierarchical Data There’ll be a problem if you try to bind a set of XML data generated by ADO. Because IE doesn’t recognize schemas as a definition of the data. So IE sees two sets of data – the schema and the actual <XML> <s:Schema> ….. schema data </s:Schema> <rs:data> <z:row … /> <z:row … /> </rs:data> </XML>
Data Islands and Binding The solution to this hierarchical binding is to use two levels of binding <TABLE ID=“tblData” DATASRC=“#dsoData” DATAFLD=“rs:data”> <TR><TD> <TABLE ID=“tblData” BORDER=“1” DATASRC =“#dsoData” DATAFLD=“z:row”> <TR> <TD> <SPAN DATAFLD=“au_id”></SPAN></TD> <TD> <SPAN DATAFLD=“au_fname”></SPAN></TD> </TR> </TABLE> </TD></TR> </TABLE>
Data Islands and Binding • <Publishers> • <Publisher> <pub_id>0736</pub_id> • <pub_name>New Moon Books</pub_name> • <city>Boston</city> • <state>MA</state> • <country>USA</country> • <titles> <title_id>BU2075</title_id> • <title>You Can Combat Computer Stress!</title> • <price>$2.99</price> • <pubdate>6/30/91</pubdate> • <sale> • <stor_id>7896</stor_id> • <ord_num>X999</ord_num> • <ord_date>2/21/93</ord_date> • <qty>35</qty> • </sale> • </titles> • <employee> <emp_id>PDH4740M</emp_id> • <fname>Palle</fname> • <minit>D</minit> • <lname>Ibsen</lname> • </employee> • <employee> <emp_id>KFJ64308F</emp_id> • <fname>Karin</fname> • <minit>F</minit> • <lname>Josephs</lname> • </employee> • </Publisher> • </Publishers>
<HTML><HEAD><TITLE>DataBinding.html</TITLE></HEAD> • <BODY> • <XML ID="dsoData" SRC="publishers.xml"></XML> • <TABLE ID="tblPublishers" DATASRC="#dsoData" BORDER="1"> • <TR><TD><DIV DATAFLD = "pub_name"></DIV></TD> • <TD><DIV DATAFLD = "city"></DIV></TD> • <TD><DIV DATAFLD = "state"></DIV></TD> </TR> • <TR> <TD COLSPAN=4> • <TABLE> • <TR><TD>Titles</TD> </TR> • <TR><TD COLSPAN=4> • <TABLE DATASRC="#dsoData" DATAFLD="titles" BORDER="1"> • <TR><TD><DIV DATAFLD = "title"></DIV></TD><TD><DIV DATAFLD = "price"></DIV></TD> • </TR> • <TR><TD COLSPAN=3> • <TABLE DATASRC="#dsoData" DATAFLD="sale" BORDER="1"> • <TR><TD><DIV DATAFLD = "ord_date"></DIV></TD><TD><DIV DATAFLD = "qty"></DIV></TD></TR> • </TABLE> • </TD> • </TR> • </TABLE> • </TD> </TR> • <TR> <TD>Employees</TD></TR> • <TR> <TD COLSPAN=4> • <TABLE DATASRC="#dsoData" DATAFLD="employee" BORDER="1"> • <TR><TD><DIV DATAFLD = "fname"></DIV></TD> <TD><DIV DATAFLD = "lname"></DIV></TD> </TR> • </TABLE> • </TD> </TR> • </TABLE> • </TD> • </TR> • </TABLE> • </BODY>
Saving Recordsets as XML • ADO generate XML recordsets by using the Save method of the Recordset object, and specifying the format as adPersistXML or 1. • Persisting ADO Recordsets to a Stream A Stream is simply a block of data in memory, which is not processed in any way. ADO 2.5 introduces the new Stream object, and can be the target for saving a recordset Set rsAuthors = Server.CreateObject(“ADODB.Recordset”) Set stmAuthors = Server.CreateObject(“ADODB.Stream”) rsAuthors.Open “authors”, strConn rsAuthors.Save stmAuthors, 1 ‘adPersistXML
Saving Recordsets as XML Use the methods and properties of the stream to manipulate the data. For example, extract the XML into a string using the ReadText method: At this stage strXMLAuthors contains the complete XML recordset, including the schema. • Persisting ADO Recordsets to the Response Object Saves the recordset as XML directly into the Response object. strXMLAuthors = stmAuthors.ReadText rsAuthors.Save Response, 1 ‘adPersistXML
Saving Recordsets as XML <% ‘Using the DOM to create a Data Island • Dim strConn • Dim xmlDOM • Dim strXML • Set rsAuthors = Server.CreateObject("ADODB.Recordset") • Set xmlDOM = Server.CreateObject("MSXML.DOMDocument") • rsAuthors.Open "authors", strConn • rsAuthors.Save xmlDOM, 1 • rsAuthors.Close • Set rsAuthors = Nothing • strXML = xmlDOM.xml • strXML = "<XML" & Mid(strXML,5,Len(strXML)-10) & "XML>" • Response.Write strXML %>
Saving Recordsets as XML <XML ID="dsoAuthors"> <% ‘Using Response to Create a Data Island • Dim rsAuthors • Set rsAuthors = Server.CreateObject ("ADODB.Recordset") • rsAuthors.Open "authors", strConn • rsAuthors.Save Response, 1 • rsAuthors.Close • Set rsAuthors = Nothing %> </XML> To see the result on our HTML page, activate the View Source menu
Saving Recordsets as XML <xml xmlns:s='uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882' xmlns:dt='uuid:C2F41010-65B3-11d1-A29F-00AA00C14882' xmlns:rs='urn:schemas-microsoft-com:rowset' xmlns:z='#RowsetSchema'> <s:Schema id='RowsetSchema'> <s:ElementType name='row' content='eltOnly' rs:CommandTimeout='30'> <s:AttributeType name='au_id' rs:number='1' rs:writeunknown='true'> <s:datatype dt:type='string' rs:dbtype='str' dt:maxLength='11' rs:maybenull='false'/> </s:AttributeType> <s:AttributeType name='au_lname' rs:number='2' rs:writeunknown='true'> <s:datatype dt:type='string' rs:dbtype='str' dt:maxLength='40' rs:maybenull='false'/> </s:AttributeType> …. <s:extends type='rs:rowbase'/> </s:ElementType> </s:Schema> <rs:data> <z:row au_id='172-32-1176' au_lname='White' au_fname='Johnson' phone='408 496-7223' address='10932 Bigge Rd.' city='Menlo Park' state='CA' zip='94025' contract='True'/> <z:row au_id='213-46-8915' au_lname='Green' au_fname='Marjorie' phone='415 986-7020' address='309 63rd St. #411' city='Oakland' state='CA' zip='94618' contract='True'/> <z:row au_id='238-95-7766' au_lname='Carson' au_fname='Cheryl' phone='415 548-7723' address='589 Darwin Ln.' city='Berkeley' state='CA' zip='94705' contract='True'/> <z:row au_id='267-41-2394' au_lname='O'Leary' au_fname='Michael' phone='408 286-2428' address='22 Cleveland Av. #14' city='San Jose' state='CA' zip='95128' contract='True'/> <z:row au_id='274-80-9391' au_lname='Straight' au_fname='Dean' phone='415 834-2919' address='5420 College Av.' city='Oakland' state='CA' zip='94609' contract='True'/> <z:row au_id='341-22-1782' au_lname='Smith' au_fname='Meander' phone='913 843-0462' address='10 Mississippi Dr.' city='Lawrence' state='KS' zip='66044' contract='False'/> <z:row au_id='409-56-7008' au_lname='Bennet' au_fname='Abraham' phone='415 658-9932' address='6223 Bateman St.' city='Berkeley' state='CA' zip='94705' contract='True'/> …. </rs:data> </xml>
Opening Recordsets • <% • Set rsData = Server.CreateObject("ADODB.Recordset") • Set stmData = Server.CreateObject("ADODB.Stream") • Set domXML = Server.CreateObject("MSXML.DOMDocument") • rsData.Open "authors", strConn • rsData.Save domXML, 1 ‘adPersistXML=1 • rsData.Close • stmData.Open • stmData.WriteText domXMl.xml • stmData.SetEOS • stmData.Position = 0 • rsData.Open stmData • Response.Write "<H1>Opening Authors Recordset from a DOM Object<HR></H1>" • Response.Write "<TABLE><TR><TD>au_id</TD><TD>au_fname</TD><TD>au_lname</TD><TD>phone</TD></TR>” • While rsData.EOF=False • Response.Write "<TR>" • Response.Write "<TD><INPUT TYPE='TEXT' VALUE=" & rsData(0) & "></INPUT></TD>" • Response.Write "<TD><INPUT TYPE='TEXT' VALUE=" & rsData(1) & "></INPUT></TD>" • Response.Write "<TD><INPUT TYPE='TEXT' VALUE=" & rsData(2) & "></INPUT></TD>" • Response.Write "<TD><INPUT TYPE='TEXT' VALUE=" & rsData(3) & "></INPUT></TD>" • Response.Write "</TR>" • rsData.moveNext • Wend • Response.Write "</TABLE>" • %>
Extensible Styling Language (XSL) • XSL is an XML-based language to allow us to transform XML data. • This transformation can be between one format of XML and another, or from XML to HTML or from XML to any type of text output. • XML tags just identify the data. If we want to display XML data we need to style it in some way. • XSL made up of two parts: • a transformation language • a formatting language
Extensible Styling Language (XSL) • XSL Stylesheets • The idea behind XSL is that we have a set of rules that match elements or attributes in the XML. • These rules are known as template, and within a template we can loop through elements and attributes, apply other templates and perform other types of processing • Text that is not part of an XSL processing instruction is output, so this is how we transform XML – by matching elements and outputting text and element values
Extensible Styling Language (XSL) • XSL Stylesheets • The top-level tag identifies the stylesheet and the namespace, which applies to it. This finishing tag: • within the stylesheet, the tags take the form of templates, which match portions of the XML document. <xsl:stylesheet xmlns:xsl=http://www.w3.org/TR/WD-xsl> </xsl:stylesheet>
Extensible Styling Language (XSL) • This stylesheet converts an ADO recordset in XML into an HTML table. <xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl"> <xsl:template match ="/"> <HTML> <BODY> <xsl:apply-templates select="//rs:data" /> </BODY> </HTML> </xsl:template> <xsl:template match="//rs:data"> <TABLE BORDER="1"> <xsl:for-each select="z:row"> <TR> <xsl:for-each select="(@*)"> <TD> <xsl:value-of/> </TD> </xsl:for-each> </TR> </xsl:for-each> </TABLE> </xsl:template> </xsl:stylesheet>
Extensible Styling Language (XSL) • We start with the stylesheet declaration: • The first command is a template command telling us which element we should match. In this case, we are matching the root element, denoted by the / symbol: • At this stage we have started the processing of the XML tree. If we are converting to HTML, we need to output HTML tags that start an HTML document. <xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl"> <xsl:template match ="/"> <HTML> <BODY>
Extensible Styling Language (XSL) • Now we need to find the actual data. Use apply-templates to search for another template. This template will be applied, and once all processing in it has completed, processing returns to the current template. • After the inner template has been processed we can finish off our HTML document <xsl:apply-templates select="//rs:data" /> </BODY> </HTML> </xsl:template>
Extensible Styling Language (XSL) • To process each row of data, use the “for-each” statement, which is as much the same as a “for..each” loop in VBScript. The “select” part of the statement tells XSL which elements to loop though. • To process the attributes, again use the “for-each” construct, with a different “select”. To match an attribute, we have to use the @ symbol, so @* means match every attribute. <xsl:for-each select="z:row"> <xsl:for-each select="(@*)">
Extensible Styling Language (XSL) • The “value-of” instruction tells XSL to output the value of a node. And since we are not stating anything specific to output, the value of the current node is output: • Embedded Styling The easiest way to apply an XSL stylesheet is to specify it in the XML file. <xsl:value-of/> <?xml-stylesheet type=“text/xsl” href=“xsl_file_name.xsl”?>
Extensible Styling Language (XSL) • <?xml version = "1.0"?> • <?xml:stylesheet type = "text/xsl" href = "contact_list.xsl"?> • <!-- contact.xml --> • <contacts> • <contact> • <lastname>Black</lastname> • <firstname>John</firstname> • </contact> • <contact> • <lastname>Green</lastname> • <firstname>Sue</firstname> • </contact> • <contact> • <lastname>Red</lastname> • <firstname>Bob</firstname> • </contact> • <contact> • <lastname>Blue</lastname> • <firstname>Mary</firstname> • </contact> • <contact> • <lastname>White</lastname> • <firstname>Mike</firstname> • </contact> • <contact> • <lastname>Brown</lastname> • <firstname>Jane</firstname> • </contact> • </contacts>
<?xml version = "1.0"?> • <xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl"> • <!-- contact_list.xsl --> • <xsl:template match ="/"> • <HTML> • <BODY> • <DIV ID = "data"> <xsl:apply-templates/> </DIV> • <SCRIPT TYPE="text/javascript" LANGUAGE="JavaScript"> • <xsl:comment><![CDATA[ • var styleSheet = document.XSLDocument; • var xmlDocument = document.XMLDocument; • function update(scope, sortKey) • { • var sortBy = styleSheet.selectSingleNode("//@order-by"); • sortBy.value = sortKey; • var scopeBy = styleSheet.selectSingleNode("//xsl:for-each/@select"); • scopeBy.value = scope; • data.innerHTML = xmlDocument.documentElement.transformNode(styleSheet); • } • ]]> • </xsl:comment> • </SCRIPT> • <TABLE BORDER = "1" DATASRC = "#xmlData" DATAPAGESIZE = "4" ID = "tbl"> • <THEAD> • <TR> <TH>Last Name</TH> <TH>First Name</TH> </TR> • </THEAD> • <TR> <TD><SPAN DATAFLD = "lastname"></SPAN></TD> • <TD><SPAN DATAFLD = "firstname"></SPAN></TD> • </TR> • </TABLE>
<INPUT TYPE = "button" VALUE = "Revert" ONCLICK = "update('contact','+firstname;+lastname');"/> • <BR/> • <INPUT TYPE = "button" VALUE = "Sort By Last Name" ONCLICK = "update('contact','+lastname;+firstname');"/> • <INPUT TYPE = "button" VALUE = "Sort By First Name" ONCLICK = "update('contact','-firstname;+lastname');"/> • <BR/> • <INPUT TYPE = "button" VALUE = "Filter Last Name Start with 'B'" • ONCLICK = "update('contact[lastname > \'B\' and lastname < \'C\']','+firstname;+lastname');"/> • <BR/> • <INPUT TYPE = "button" VALUE = "|<" ONCLICK = "tbl.firstPage();"/> • <INPUT TYPE = "button" VALUE = "<" ONCLICK = "tbl.previousPage();"/> • <INPUT TYPE = "button" VALUE = ">" ONCLICK = "tbl.nextPage();"/> • <INPUT TYPE = "button" VALUE = ">|" ONCLICK = "tbl.lastPage();"/> • </BODY> • </HTML> • </xsl:template> • <xsl:template match="contacts"> • <XML ID = "xmlData"> • <contacts> • <xsl:for-each select = "contact" • order-by = "+firstname;+lastname"> • <contact> • <lastname><xsl:value-of select = "lastname"/> </lastname> • <firstname><xsl:value-of select = "firstname"/> </firstname> • </contact> • </xsl:for-each> • </contacts> • </XML> • </xsl:template> • </xsl:stylesheet>