Table continued on following page 409 Using XML in Visual Basic 2005 Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com... The previous code also introduced two me
Trang 1and so for this type, subroutine ShowXmlNodeonly displays the properties NodeTypeand Value For allother node types, the Name, AttributeCount, Value, and NodeTypeproperties are displayed.
For the finalization of this module, add a Sub Mainas follows:
Sub Main(ByVal args() As String)
ReadMovieXml(“ \MovieManage.xml”)End Sub
An example construction of the MovieManage.xmlfile is:
Trang 2Running this module produces the following output (a partial display since it would be rather lengthy):Name: xml, Type: XmlDeclaration, AttributeCount: 2, Value: version=”1.0”
encoding=”utf-8”
Name: version, Type: Attribute, AttributeCount: 2, Value: 1.0Name: encoding, Type: Attribute, AttributeCount: 2, Value: utf-8Type: Whitespace
Name: MovieOrderDump, Type: Element, AttributeCount: 0, Value:
Type: WhitespaceName: FilmOrder_Multiple, Type: Element, AttributeCount: 0, Value:
Type: WhitespaceName: multiFilmOrders, Type: Element, AttributeCount: 0, Value:
Type: WhitespaceName: FilmOrder, Type: Element, AttributeCount: 0, Value:
Type: WhitespaceName: name, Type: Element, AttributeCount: 0, Value:
Type: Text, Value: GreaseThis example managed to use three methods and five properties of XmlReader The output generatedwas informative but far from practical XmlReaderexposes over 50 methods and properties, which meansthat you have only scratched the surface of this highly versatile class The remainder of this section willlook at the XmlReaderSettingsclass, introduce a more realistic use of XmlReader,and demonstratehow the classes of System.Xmlhandle errors
The XmlReaderSettings Class
Just like the XmlWriterobject, the XmlReaderobject requires settings to be applied for instantiation ofthe object This means that you can apply settings for how the XmlReaderobject behaves for when it isreading whatever XML that you might have for it This includes settings for how to deal with whitespace, schemas, and more The following table details these settings
Property Initial Value Description
CheckCharacters True This property, if set to True, will
perform a character check upon the contents of the retrieved object Legalcharacters can be found at www.w3.org/TR/REC-xml#charsets
CloseInput False This property gets or sets a value
indicat-ing whether the underlyindicat-ing stream orSystem.IO.TextReader should beclosed when the reader is closed
ConformanceLevel ConformanceLevel Allows for the XML to be checked to
.Document make sure that it follows certain specified
rules Possible conformance level settingsinclude Document, Fragment, andDefault
DtdValidate False Defines whether the XmlReadershould
perform a DTD validation
Table continued on following page
409
Using XML in Visual Basic 2005
Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 3Property Initial Value Description
IgnoreComments False Defines whether comments should be
ignored or not
IgnoreInlineSchema True Defines whether any inline schemas
should be ignored or not
IgnoreProcessing False Defines whether processing instructions
ignored
noNamespaceSchemaLocationattributes should be ignored or not.IgnoreValidation True Defines whether the XmlReaderobject
IgnoreWhitespace False Defines whether the XmlReaderobject
should ignore all insignificant whitespace
LineNumberOffset 0 Defines the line number which the
LineNumberproperty starts countingwithin the XML file
LinePositionOffset 0 Defines the line number which the
LineNumberproperty starts countingwith the XML file
NameTable An empty Allows the XmlReaderto work with a
XmlNameTable specific XmlNameTableobject that is used object for atomized string comparisons.ProhibitDtd True This property gets or sets a value indi-
cating whether to prohibit documenttype definition (DTD) processing
XmlSchemaSet with an instance of the XmlSchemaSet
ValidationFlags This property gets or sets a value
indicating the schema validation settings.ValidationType ValidationType This property gets or sets a value
.None indicating whether the System.Xml
.XmlReaderwill perform validation ortype assignment when reading
XmlResolver A newXmlResolver This property sets the XmlResolverto
with no credentials access external documents
410
Chapter 12
Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 4An example of using this setting class to modify the behavior of the XmlReader class is:
Dim myXmlSettings As New XmlReaderSettings()myXmlSettings.IgnoreWhitespace = TruemyXmlSettings.IgnoreComments = TrueUsing readMovieInfo As XmlReader = XmlReader.Create(fileName, myXmlSettings)
‘ Use XmlReader object here
End Using
In this case, the XmlReaderobject that is created will behave in that it will ignore the white space that itencounters as well as ignoring any of the XML comments These settings, once established with theXmlReaderSettingsobject are then associated to the XmlReaderobject through its Createmethod
Traversing XML Using XmlTextReader
An application can easily use XmlReaderto traverse a document that is received in a known format Thedocument can thus be traversed in a deliberate manner You implemented a class that serialized arrays
of movie orders The next example will take an XML document containing multiple XML documents ofthat type and traverse them Each movie order will be forwarded to the movie supplier by sending a fax.The document will be traversed as follows:
Read root element: <MovieOrderDump>
Process each <FilmOrder_Multiple> elementRead <multiFilmOrders> element
Process each <FilmOrder>
Send fax for each movie order hereThe basic outline for the program’s implementation is to open a file containing the XML document toparse and to traverse it from element to element
Dim myXmlSettings As New XmlReaderSettings()Using readMovieInfo As XmlReader = XmlReader.Create(fileName, myXmlSettings)readMovieInfo.Read()
End UsingThe previous code opened the file using the constructor of XmlReader, and the End Usingstatementtakes care of shutting everything down for you The previous code also introduced two methods of theXmlReaderclass:
411
Using XML in Visual Basic 2005
Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 5❑ ReadStartElement(String)— This verifies that the current in the stream is an element and that the element’s name matches the string passed to method ReadStartElement If theverification is successful, the stream is advanced to the next element.
❑ ReadEndElement()— This verifies that the current element is an end tab, and if the verification
is successful the stream is advanced to the next element
The application knows that an element, <MovieOrderDump>, will be found at a specific point in the document The ReadStartElementmethod verifies this foreknowledge of the document format Onceall the elements contained in element <MovieOrderDump>have been traversed, the stream should point
to the end tag </MovieOrderDump> The ReadEndElementmethod verifies this
The code that traverses each element of type <FilmOrder>similarly uses the ReadStartElementandReadEndElementmethods to indicate the start and end of the <FilmOrder>and <multiFilmOrders>elements The code that ultimately parses the list of prescription and faxes the movie supplier (using theFranticallyFaxTheMovieSuppliersubroutine) is:
Dim myXmlSettings As New XmlReaderSettings()
Using readMovieInfo As XmlReader = XmlReader.Create(fileName, myXmlSettings)
readMovieInfo.Read()readMovieInfo.ReadStartElement(“MovieOrderDump”)
Do While (True)readMovieInfo.ReadStartElement(“FilmOrder_Multiple”)readMovieInfo.ReadStartElement(“multiFilmOrders”)
Do While (True)readMovieInfo.ReadStartElement(“FilmOrder”)movieName = readMovieInfo.ReadElementString()movieId = readMovieInfo.ReadElementString()quantity = readMovieInfo.ReadElementString()readMovieInfo.ReadEndElement() ‘ clear </FilmOrder>
FranticallyFaxTheMovieSupplier(movieName, movieId, quantity)
‘ Should read next FilmOrder node
‘ else quitsreadMovieInfo.Read()
If (“FilmOrder” <> readMovieInfo.Name) ThenExit Do
End IfLoopreadMovieInfo.ReadEndElement() ‘ clear </multiFilmOrders>
readMovieInfo.ReadEndElement() ‘ clear </FilmOrder_Multiple>
‘ Should read next FilmOrder_Multiple node
‘ else you quitreadMovieInfo.Read() ‘ clear </MovieOrderDump>
If (“FilmOrder_Multiple” <> readMovieInfo.Name) ThenExit Do
Trang 6LoopreadMovieInfo.ReadEndElement() ‘ </MovieOrderDump>
End UsingThree lines within the previous code contain a call to the ReadElementStringmethod:
movieName = readMovieInfo.ReadElementString()movieId = readMovieInfo.ReadElementString()quantity = readMovieInfo.ReadElementString()While parsing the stream, it was known that an element named <name>existed and that this elementcontained the name of the movie Rather than parsing the start tag, getting the value, and parsing the end tag, it was easier just to get the data using the ReadElementStringmethod This methodretrieves the data string associated with an element and advances the stream to the next element TheReadElementStringmethod was also used to retrieve the data associated with the XML elements
<filmId>and <quantity>.The output of this example was a fax, which we won’t show because the emphasis of this example is onshowing that it is simpler to traverse a document when its form is known The format of the document isstill verified by XmlReaderas it is parsed
The XmlReaderclass also exposes properties that give more insight into the data contained in the XMLdocument and the state of parsing: IsEmptyElement, EOF, and IsStartElement This class also allowsdata in a variety of forms to be retrieved using methods such as ReadBase64, ReadHex, and ReadChars.The raw XML associated with the document can also be retrieved, using ReadInnerXmland
ReadOuterXml Once again, you have only scratched the surface of the XmlReaderclass You will findthis class to be quite rich in functionality
TrymovieReadXML(“ \Malformed.xml”)Catch xmlEx As XmlException
Console.Error.WriteLine(“XML Error: “ + xmlEx.ToString())Catch ex As Exception
Console.Error.WriteLine(“Some other error: “ + ex.ToString())End Try
413
Using XML in Visual Basic 2005
Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 7The methods and properties exposed by the XmlReaderclass raise exceptions of type System
.Xml.XmlException In fact, every class in the System.Xmlnamespace raises exceptions of typeXmlException Although this is a discussion of errors using an instance of type XmlReader, the con-cepts reviewed apply to all errors generated by classes found in the System.Xmlnamespace
The properties exposed by XmlExceptioninclude
❑ LineNumber— The number of the line within an XML document where the error occurred
❑ LinePosition— The position within the line specified by LineNumberwhere the erroroccurred
❑ Message— The error message that corresponds to the error that occurred This error took place
at the line in the XML document specified by LineNumberand within the line at the positionspecified by LinePostion
❑ SourceUri— Provides the URI of the element or document in which the error occurred.The error displayed when subroutine movieReadXMLprocesses malformed.xmlis:
XML Error: System.Xml.XmlException: The ‘,’ character, hexadecimal value 0x2C,cannot begin a name Line 2, position 49
Looking closely at the document, there is a comma separating the attributes in element, <FilmOrder>(ElokuvaTilaus=”101”, Maara=”10”) This comma is invalid Removing the comma and running thecode again gives the following output:
XML Error: System.Xml.XmlException: This is an unexpected token Expected
‘EndElement’ Line 5, position 27
Once again, you can recognize the precise error In this case, you do not have an end element,
</ElokuvaTilaus>, but you do have an opening element, <ElokuvaTilaus>
The properties provided by the XmlExceptionclass (LineNumber, LinePosition, and Message) provide a useful level of precision when tracking down errors The XmlReaderclass also exposes a level
of precision with respect to the parsing of the XML document This precision is exposed by the
XmlReaderthrough properties such as LineNumberand LinePosition
Using the MemoryStream Object
A very useful class that can greatly help you when working with XML is System.IO.MemoryStream.Rather than needing a network or disk resource backing the stream (as in System.Net.Sockets.NetworkStreamand System.IO.FileStream), MemoryStreambacks itself onto a block of memory.Imagine that you want to generate an XML document and email it The built-in classes for sending emailrely on having a System.Stringcontaining a block of text for the message body But, if you want togenerate an XML document, you need a stream
If the document is reasonably sized, you should write the document directly to memory and copy thatblock of memory to the email This is good from a performance and reliability perspective because youdon’t have to open a file, write it, rewind it, and read the data back in again However, you must con-sider scalability in this situation because if the file is very large, or you have a great number of smallerfiles, you could run out of memory (in which case you’ll have to go the “file” route)
414
Chapter 12
Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 8In this section, you’ll see how to generate an XML document to a MemoryStreamobject You’ll read thedocument back out again as a System.Stringvalue and email it What you’ll do is create a new classcalled EmailStreamthat extends MemoryStream This new class will contain an extra method calledCloseAndSendthat, as its name implies, will close the stream and send the email message.
First, you’ll create a new console application project called EmailStream The first job is to create a basicCustomerobject that contains a few basic members and that can be automatically serialized by NETthrough use of the SerializableAttributeattribute:
<Serializable()> Public Class Customer
‘ members
Public Id As IntegerPublic FirstName As StringPublic LastName As StringPublic Email As StringEnd Class
The fun part now is the EmailStreamclass itself This needs access to the System.Web.Mailnamespace,
so you’ll need to add a reference to the System.Webassembly The new class should also extendSystem.IO.MemoryStream, as shown here:
Imports System.IOImports System.Web.MailPublic Class EmailStreamInherits MemoryStreamThe first job of CloseAndSendis to start putting together the mail message This is done by creating anew System.Web.Mail.MailMessageobject and configuring the sender, recipient, and subject
‘ CloseAndSend - close the stream and send the email
Public Sub CloseAndSend(ByVal fromAddress As String, _
ByVal toAddress As String, _ByVal subject As String)
‘ Create the new message
Dim message As New MailMessagemessage.From = fromAddressmessage.To = toAddressmessage.Subject = subject
This method will be called once the XML document has been written to the stream, so you can assume atthis point that the stream contains a block of data To read the data back out again, you have to rewind thestream and use a System.IO.StreamReader Before you do this, the first thing you should do is callFlush Traditionally, streams have always been buffered, that is, the data is not sent to the final destination(the memory block in this case, but a file in the case of a FileStreamand so on) each and every time thestream is written Instead, the data is written in (pretty much) a nondeterministic way Because you need allthe data to be written, you call Flushto ensure that all the data has been sent to the destination and thatthe buffer is empty
415
Using XML in Visual Basic 2005
Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 9In a way, EmailStreamis a great example of buffering All of the data is held in a memory “buffer” untilyou finally send the data on to its destination in a response to an explicit call to this method:
‘ Flush and rewind the stream
Flush()Seek(0, SeekOrigin.Begin)Once you’ve flushed and rewound the stream, you can create a StreamReaderand dredge all the dataout into the Bodyproperty of the MailMessageobject:
‘ Read out the data
Dim reader As New StreamReader(Me)message.Body = reader.ReadToEnd()After you’ve done that, you close the stream by calling the base class method:
‘ Close the stream
Close()
Finally, you send the message:
‘ Send the message
SmtpMail.Send(message)End Sub
To call this method, you need to add some code to the Mainmethod First, you create a new Customerobject and populate it with some test data:
Imports System.Xml.Serialization
Module Module1
Sub Main()
‘ Create a new customer
Dim customer As New Customercustomer.Id = 27
416
Chapter 12
Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 10‘ Create a new email stream
Dim stream As New EmailStream
‘ Serialize
Dim serializer As New XmlSerializer(customer.GetType())serializer.Serialize(stream, customer)
At this point, the stream will be filled with data, and after all the data has been flushed, the block
of memory that EmailStreambacks on to will contain the complete document Now, you can callCloseAndSendto email the document
‘ Send the email
stream.CloseAndSend(“evjen@yahoo.com”, _
“evjen@yahoo.com”, “XML Customer Document”)End Sub
End ModuleYou probably already have Microsoft SMTP Service properly configured — this service is necessary
to send email You also need to make sure that the email addresses used in your code goes to your email address! Run the project, check your email, and you should see something, as shown in Figure 12-2
Figure 12-2
417
Using XML in Visual Basic 2005
Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 11Document Object Model (DOM)
The classes of the System.Xmlnamespace that support the Document Object Model (DOM) interact asillustrated in Figure 12-3
Figure 12-3
Within this diagram, an XML document is contained in a class named XmlDocument Each node withinthis document is accessible and managed using XmlNode Nodes can also be accessed and managedusing a class specifically designed to process a specific node’s type (XmlElement, XmlAttribute, and
so on) XML documents are extracted from XmlDocumentusing a variety of mechanisms exposedthrough such classes as XmlWriter, TextWriter, Stream, and a file (specified by file name of typeString) XML documents are consumed by an XmlDocumentusing a variety of load mechanismsexposed through the same classes
Where a DOM-style parser differs from a stream-style parser is with respect to movement Using DOM,the nodes can be traversed forward and backward Nodes can be added to the document, removed fromthe document, and updated However, this flexibility comes at a performance cost It is faster to read orwrite XML using a stream-style parser
The DOM-specific classes exposed by System.Xmlinclude
❑ XmlDocument— Corresponds to an entire XML document A document is loaded using theLoadmethod XML documents are loaded from a file (the file name specified as type String),TextReader, or XmlReader A document can be loaded using LoadXmlin conjunction with astring containing the XML document The Savemethod is used to save XML documents Themethods exposed by XmlDocumentreflect the intricate manipulation of an XML document For example, the following self-documenting creation methods are implemented by this class:CreateAttribute, CreateDataSection, CreateComment, CreateDocumentFragment,CreateDocumentType, CreateElement, CreateEntityReference, CreateNode,CreateProcessingInstruction, CreateSignificantWhitespace, CreateTextNode,CreateWhitespace, and CreateXmlDeclaration The elements contained in the documentcan be retrieved Other methods support the retrieving, importing, cloning, loading, and writing of nodes
❑ XmlNode— Corresponds to a node within the DOM tree This class supports datatypes,
namespaces, and DTDs A robust set of methods and properties are provided to create, delete, and replace nodes: AppendChild, CloneNode, InsertAfter, InsertBefore, PrependChild,
XmlMode XmlElement XmlAttribute
XmlDocument
XML DocumentObjectModel [DOM]
XmlWriter, TextWriterfile, Stream
XmlReader, TextReaderfile, Stream
418
Chapter 12
Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 12RemoveAll, RemoveChild, and ReplaceChild The contents of a node can similarly be traversed in a variety of ways: FirstChild, LastChild, NextSibling, ParentNode, andPreviousSibling.
❑ XmlElement— Corresponds to an element within the DOM tree The functionality exposed by this class contains a variety of methods used to manipulate an element’s attributes:GetAttribute, GetAttributeNode, RemoveAllAttributes, RemoveAttributeAt,
RemoveAttributeNode, SetAttribute, and SetAttributeNode
❑ XmlAttribute— Corresponds to an attribute of an element (XmlElement) within the DOM tree
An attribute contains data and lists of subordinate data For this reason, it is a less complicatedobject than an XmlNodeor an XmlElement An XmlAttributecan retrieve its owner document(property, OwnerDocument), retrieve its owner element (property, OwnerElement), retrieve its parent node (property, ParentNode), and retrieve its name (property, Name) The value of anXmlAttributeis available via a read-write property named Value
Given the diverse number of methods and properties (and there are many more than those listed here)exposed by XmlDocument, XmlNode, XmlElement, and XmlAttribute, it should be clear that any XML1.0–compliant document can be generated and manipulated using these classes In comparison to theirXML stream counterparts, these classes afford more flexible movement within and editing of XMLdocuments
A similar comparison could be made between DOM and data serialized and deserialized using XML.Using serialization, the type of node (for example, attribute or element) and the node name are specified
at compile time There is no on-the-fly modification of the XML generated by the serialization process.Other technologies that generate and consume XML are not as flexible as DOM This includes ADO.NETand ADO, which generate XML of a particular form Out of the box, SQL Server 2000 does expose a certain amount of flexibility when it comes to the generation (FOR XMLqueries) and consumption of XML(OPENXML) SQL Server 2005 has more support from XML and even supports an XML datatype SQLServer 2005 also expands upon the FOR XMLquery with FOR XML TYPE The choice between using classeswithin DOM and a version of SQL Server is a choice between using a language, such as Visual Basic, tomanipulate objects or installing SQL Server and performing most of the XML manipulation in SQL
DOM Traversing Raw XML Elements
The first DOM example will load an XML document into an XmlDocumentobject using a string that contains the actual XML document This scenario is typical of an application that uses ADO.NET to generate XML but then uses the objects of DOM to traverse and manipulate this XML ADO.NET’sDataSetobject contains the results of ADO.NET data access operations The DataSetclass exposes aGetXmlmethod This method retrieves the underlying XML associated with the DataSet The followingcode demonstrates how the contents of the DataSetare loaded into the XmlDocument:
Dim xmlDoc As New XmlDocumentDim ds As New DataSet
‘ Set up ADO.NET DataSet() herexmlDoc.LoadXml(ds.GetXml())
419
Using XML in Visual Basic 2005
Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 13This example will simply traverse each XML element (XmlNode) in the document (XmlDocument) anddisplay the data accordingly The data associated with this example will not be retrieved from a DataSetbut will instead be contained in a string, rawData This string is initialized as follows:
Dim rawData As String = _
of a collection of type XmlNodeList Using the For Eachstatement to construct this list, the XmlNodeList(movieOrderNodes) can be traversed as individual XmlNodeelements (movieOrderNode) The code forhandling this is as follows:
Dim xmlDoc As New XmlDocument
Dim movieOrderNodes As XmlNodeList
Dim movieOrderNode As XmlNode
Dim baseDataNodes As XmlNodeList
Dim bFirstInRow As Boolean
Trang 14If (bFirstInRow) ThenbFirstInRow = FalseElse
Console.Out.Write(“, “)End If
Console.Out.Write(baseDataNode.Name & “: “ & baseDataNode.InnerText)Next
Console.Out.WriteLine()The bulk of the previous code retrieves the name of the node using the Nameproperty and the InnerTextproperty of the node The InnerTextproperty of each XmlNoderetrieved contains the data associatedwith the XML elements (nodes) <name>, <filmId>, and <quantity> The example displays the contents
of the XML elements using Console.Out The XML document is displayed as follows:
name: Grease, filmId: 101, quantity: 10name: Lawrence of Arabia, filmId: 102, quantity: 10Other, more practical, methods for using this data could have been implemented, including:
❑ The contents could have been directed to an ASP.NET Responseobject The data retrievedcould have been used to create an HTML table (<table>table, <tr>row, and <td>data) thatwould be written to the Responseobject
❑ The data traversed could have been directed to a ListBoxor ComboBoxWindows Forms control.This would allow the data returned to be selected as part of a GUI application
❑ The data could have been edited as part of your application’s business rules For example, youcould have used the traversal to verify that the <filmId>matched the <name> For example, ifyou really wanted to validate the data entered into the XML document in any manner
The example in its entirety is:
Dim rawData As String = _
‘ Traverse each <FilmOrder>
movieOrderNodes = xmlDoc.GetElementsByTagName(“FilmOrder”)
421
Using XML in Visual Basic 2005
Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 15For Each movieOrderNode In movieOrderNodes
baseDataNodes = movieOrderNode.ChildNodesbFirstInRow = True
For Each baseDataNode As XmlNode In baseDataNodes
If (bFirstInRow) ThenbFirstInRow = FalseElse
Console.Out.Write(“, “)End If
Console.Out.Write(baseDataNode.Name & “: “ & baseDataNode.InnerText)Next
Console.Out.WriteLine()Next
DOM Traversing XML Attributes
This next example will demonstrate how to traverse data contained in attributes and how to update theattributes based on a set of business rules In this example, the XmlDocumentobject is populated byretrieving an XML document from a file After the business rules edit the object, the data will be persistedback to the file
Dim xmlDoc As New XmlDocument
<FilmOrder name=”Grease” filmId=”101” quantity=”10” />
You have already seen how to traverse the XML elements associated with a document, so let’s assumethat you have successfully retrieved the XmlNodeassociated with the <FilmOrder>element
Dim attributes As XmlAttributeCollection
Dim filmId As Integer
Dim quantity As Integer
attributes = node.Attributes()
For Each attribute As XmlAttribute In attributes
If 0 = String.Compare(attribute.Name, “filmId”) ThenfilmId = attribute.InnerXml
ElseIf 0 = String.Compare(attribute.Name, “quantity”) Thenquantity = attribute.InnerXml
End IfNext
422
Chapter 12
Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 16The previous code traverses the attributes of an XmlNodeby retrieving a list of attributes using theAttributesmethod The value of this method is used to set the attributes object (datatype,XmlAttributeCollection) The individual XmlAttributeobjects (variable, attribute) contained inattributes are traversed using a For Eachloop Within the loop, the contents of the filmIdand thequantityattribute are saved for processing by your business rules.
Your business rules execute an algorithm that ensures that the movies in the company’s order are provided in the correct quantity This rule is that the movie associated with filmId=101must be sent tothe customer in batches of six at a time due to packaging In the event of an invalid quantity, the code forenforcing this business rule keeps removing a single order from the quantityvalue until the number isdivisible by six Then this number is assigned to the quantityattribute The Valueproperty of theXmlAttributeobject is used to set the correct value of the order’s quantity The code performing thisbusiness rule is:
If filmId = 101 Then
‘ This film comes packaged in batches of six
Do Until (quantity / 6) = Truequantity -= 1
LoopAttributes.ItemOf(“quantity”).Value = quantityEnd If
What is elegant about this example is that the list of attributes was traversed using For Each ThenItemOfwas used to look up a specific attribute that had already been traversed This would not havebeen possible by reading an XML stream with an object derived from the XML stream reader class,XmlReader
You can use this code as follows:
Sub TraverseAttributes(ByRef node As XmlNode)Dim attributes As XmlAttributeCollectionDim filmId As Integer
Dim quantity As Integerattributes = node.Attributes()For Each attribute As XmlAttribute In attributes
If 0 = String.Compare(attribute.Name, “filmId”) ThenfilmId = attribute.InnerXml
ElseIf 0 = String.Compare(attribute.Name, “quantity”) Thenquantity = attribute.InnerXml
End IfNext
If filmId = 101 Then
‘ This film comes packaged in batches of six
Do Until (quantity / 6) = Truequantity -= 1
LoopAttributes.ItemOf(“quantity”).Value = quantity
423
Using XML in Visual Basic 2005
Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 17‘ Traverse each <FilmOrder>
movieOrderNodes = xmlDoc.GetElementsByTagName(“FilmOrder”)For Each movieOrderNode As XmlNode In movieOrderNodesTraverseAttributes(movieOrderNode)
NextxmlDoc.Save(“ \MovieSupplierShippingListV2.xml”)End Sub
XSLT Transforms
XSLT is a language that is used to transform XML documents so that they can be presented visually You have performed a similar task before When working with XML serialization, you rewrote theFilmOrderclass This class was used to serialize a movie order object to XML using nodes that
contained English-language names The rewritten version of this class, ElokuvaTilaus, serialized XML nodes containing Finnish names Source Code Style attributes were used in conjunction with theXmlSerializerclass to accomplish this transformation Two words in this paragraph send chills downthe spine of any experienced developer: rewrote and rewritten The point of an XSL Transform is to use an alternate language (XSLT) to transform the XML rather than rewriting the source code, SQLcommands, or some other mechanism used to generate XML
Conceptually, XSLT is straightforward A file with an xslt extension describes the changes
(transformations) that will be applied to a particular XML file Once this is completed, an XSLT
processor is provided with the source XML file and the XSLT file, and performs the transformation TheSystem.Xml.Xsl.XslTransformclass is such an XSLT processor A new processor in NET 2.0 is theXslCompiledTransformobject found at System.Xml.XslCompiledTransform You will take a look atusing both of these processors
The XSLT file is itself an XML document, although certain elements within this document are specific commands There are dozens of XSLT commands that can be used in writing an XSLT file In thefirst example, you will explore the following XSLT elements (commands):
XSLT-❑ stylesheet— This element indicates the start of the style sheet (XSL) in the XSLT file
❑ template— This element denotes a reusable template for producing specific output This output is generated using a specific node type within the source document under a specific context For example, the text <xsl: template match=”/”>selects all root notes (“/”) for thespecific transform template
424
Chapter 12
Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 18❑ for-each— This element applies the same template to each node in the specified set Recall thatyou demonstrated a class (FilmOrder_Multiple) that could be serialized This class contained
an array of prescriptions Given the XML document generated when a FilmOrder_Multipleisserialized, each prescription serialized could be processed using <xsl:for-each select =
“FilmOrder_Multiple/multiFilmOrders/FilmOrder”>
❑ value-of— This element retrieves the value of the specified node and inserts it into the document in text form For example, <xsl:value-of select=”name” />would take the value
of XML element, <name>, and insert it into the transformed document
The FilmOrder_Multipleclass when serialized generates XML such as the following (where indicates where additional <FilmOrder>elements may reside):
a serialized version, FilmOrder_Multiple:
Using XML in Visual Basic 2005
Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 19In the previous XSLT file, the XSLT elements are marked in boldface These elements perform operations
on the source XML file containing a serialized FilmOrder_Multipleobject and generate the appropriateHTML file Your file contains a table (marked by the table tag, <TABLE>) that contains a set of rows (eachrow marked by a table row tag, <TR>) The columns of the table are contained in table data tags, <TD> Theprevious XSLT file contains the header row for the table:
Each row containing data (an individual prescription from the serialized object, FilmOrder_Multiple)
is generated using the XSLT element, for-each, to traverse each <FilmOrder>element within thesource XML document:
The code to create a displayable XML file using the XslTransformobject is:
Dim myXslTransform As XslTransform = New XslTransform
Dim destFileName As String = “ \ShowIt.html”
Trang 20destination file that will be created by the transform (file name ShowIt.html) The Startmethod of theProcessclass is used to display the HTML file The Startmethod launches a process that is most suitable for displaying the file provided Basically, the extension of the file dictates which application will be used to display the file On a typical Windows machine, the program used to display this file isInternet Explorer, as shown in Figure 12-4.
Figure 12-4
Do not confuse displaying this HTML file with ASP.NET Displaying an HTML file in this manner takes place on a single machine without the involvement of a Web server Using ASP.NET is more complex than displaying an HTML page in the default browser.
As was demonstrated, the backbone of the System.Xml.Xslnamespace is the XslTransformclass.This class uses XSLT files to transform XML documents XslTransformexposes the following methodsand properties:
❑ XmlResolver— This get/set property is used to specify a class (abstract base class, XmlResolver)that is used to handle external references (import and include elements within the style sheet).These external references are encountered when a document is transformed (method, Transform,
is executed) The System.Xmlnamespace contains a class, XmlUrlResolver, which is derivedfrom XmlResolver The XmlUrlResolverclass resolves the external resource based on a URI
❑ Load— This overloaded method loads an XSLT style sheet to be used in transforming XMLdocuments It is permissible to specify the XSLT style sheet as a parameter of type
XPathNavigator, file name of XSLT file (specified as parameter type, String), XmlReader,
or IXPathNavigable For each of type of XSLT supported, an overloaded member is provided that allows an XmlResolverto also be specified For example, it is possible to callLoad(String, XmlResolver)where Stringcorresponds to a file name and XmlResolveris
an object that handles references in the style sheet of type xsl:importand xsl:include Itwould also be permissible to pass in a value of Nothingfor the second parameter of the Loadmethod (so that no XmlResolverwould be specified) Note that there have been considerablechanges to the parameters that the Loadmethod takes between versions 1.0 and 1.1 of the NETFramework Look at the SDK documentation for details on the breaking changes that you mightencounter when working with the XslTransformclass
427
Using XML in Visual Basic 2005
Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 21❑ Transform— This overloaded method transforms a specified XML document using the
previously specified XSLT style sheet and an XmlResolver The location where the transformedXML is to be output is specified as a parameter to this method The first parameter of each overloaded method is the XML document to be transformed This parameter can be represented as an IXPathNavigable, XML file name (specified as parameter type, String), orXPathNavigator Note that there have been considerable changes to the parameters that theTransformmethod takes between versions 1.0 and 1.1 of the NET Framework Look at the SDKdocumentation for details on the breaking changes that you might encounter when working withthe XslTransformclass
The most straightforward variant of the Transformmethod is Transform(String, String,
XmlResolver) In this case, a file containing an XML document is specified as the first parameter, and a file name that receives the transformed XML document is specified as the second parameter, andthe XmlResolverused as the third parameter This is exactly how the first XSLT example utilized theTransformmethod:
myXslTransform.Transform(“ \FilmOrders.xml”, destFileName)
The first parameter to the Transformmethod can also be specified as IXPathNavigableor
XPathNavigator Either of these parameter types allows the XML output to be sent to an object of type Stream, TextWriter, or XmlWriter When these two flavors of input are specified, a parametercontaining an object of type XsltArgumentListcan be specified An XsltArgumentListobject contains a list of arguments that are used as input to the transform
When working with a NET 2.0 project, it is preferable to use the XslCompiledTransformobject instead
of the XslTransformobject, because the XslTransformobject is considered obsolete When using thenew XslCompiledTransformobject, you construct the file using the following code:
Dim myXsltCommand As New XslCompiledTransform()
Dim destFileName As String = “ \ShowIt.html”
XslCompiledTransform.Load (IXPathNavigable, XsltSettings, XmlResolver)
XslCompiledTransform.Load (String, XsltSettings, XmlResolver)
XslCompiledTransform.Load (XmlReader, XsltSettings, XmlResolver)
In this case, Stringis a representation of the xslt file that should be used in the transformation
XmlResolverhas already been explained and XsltSettingsis an object that allows you to definewhich XSLT additional options to permit The previous example used a single parameter, String, whichshowed the location of the style sheet:
Trang 22The XslCompiledTransformobject’s Transformmethod provides the following signatures:
XslCompiledTransform.Transform (IXPathNavigable, XmlWriter)XslCompiledTransform.Transform (String, String)
XslCompiledTransform.Transform (String, XmlWriter)XslCompiledTransform.Transform (XmlReader, XmlWriter)XslCompiledTransform.Transform (IXPathNavigable, XsltArgumentList, Stream)XslCompiledTransform.Transform (IXPathNavigable, XsltArgumentList, TextWriter)XslCompiledTransform.Transform (IXPathNavigable, XsltArgumentList, XmlWriter)XslCompiledTransform.Transform (String, XsltArgumentList, Stream)
XslCompiledTransform.Transform (String, XsltArgumentList, TextWriter)XslCompiledTransform.Transform (String, XsltArgumentList, XmlWriter)XslCompiledTransform.Transform (XmlReader, XsltArgumentList, Stream)XslCompiledTransform.Transform (XmlReader, XsltArgumentList, TextWriter)XslCompiledTransform.Transform (XmlReader, XsltArgumentList, XmlWriter)XslCompiledTransform.Transform (XmlReader, XsltArgumentList, XmlWriter, XmlResolver)
In this case, Stringrepresents the location of specific files (whether it is source files or output files).Some of the signatures also allow for output to XmlWriterobjects, streams, and TextWriterobjects.These can be done by also providing additional arguments using the XsltArgumentListobject In theprevious example, you used the second signature XslCompiledTransform.Transform(String,String), which asked for the source file and the destination file (both string representations of the location of said files)
myXsltCommand.Transform(“ \FilmOrders.xml”, destFileName)The XslCompiledTransformobject example will produce the same table as was generated using theXslTransformobject
XSLT Transforming between XML Standards
The first example used four XSLT elements to transform an XML file into an HTML file Such an examplehas merit, but it does not demonstrate an important use of XSLT Another major application of XSLT is totransform XML from one standard into another standard This may involve renaming elements/attributes,excluding elements/attributes, changing datatypes, altering the node hierarchy, and representing elements
as attributes and vice versa
A case of differing XML standards could easily happen to your software that automates movie orderscoming into a supplier Imagine that the software, including its XML representation of a movie order, is
so successful that you sell 100,000 copies However, just as you’re celebrating, a consortium of the largestmovie supplier chains announces that they will no longer be accepting faxed orders and that they areintroducing their own standard for the exchange of movie orders between movie sellers and buyers.Rather than panic, you simply ship an upgrade that comes complete with an XSLT file This upgrade (abit of extra code plus the XSLT file) transforms your XML representation of a movie order into the XMLrepresentation dictated by the consortium of movie suppliers Using an XSLT file allows you to ship theupgrade immediately If the consortium of movie suppliers revises their XML representation, you are notobliged to change your source code Instead, you can simply ship the upgraded XSLT file that willensure that each movie order document is compliant
429
Using XML in Visual Basic 2005
Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 23Using XML in Visual Basic 2005
The specific source code that executes the transform is:
Dim myXsltCommand As New XslCompiledTransform()
myXsltCommand.Load(“ \ConvertLegacyToNewStandard.xslt”)
myXsltCommand.Transform(“ \MovieOrdersOriginal.xml”, “ \MovieOrdersModified.xml”)The three lines of code are
1. Create an XslCompiledTransformobject
2. Use the Loadmethod to load an XSLT file (ConvertLegacyToNewStandard.xslt)
3. Use the Transformmethod to transform a source XML file (MovieOrdersOriginal.xml) into
a destination XML file (MovieOrdersModified.xml)
Recall that the input XML document (MovieOrdersOriginal.xml) does not match the format required
by your consortium of movie supplier chains The content of this source XML file is:
❑ Rename element <FilmOrder_Multiple>to <Root>
❑ Remove element <multiFilmOrders>
❑ Rename element <FilmOrder>to <DvdOrder>
❑ Remove element <name>(the film’s name is not to be contained in the document)
❑ Rename element <quantity>to HowMuchand make HowMuchan attribute of <DvdOrder>
❑ Rename element <filmId>to FilmOrderNumberand make FilmOrderNumberan attribute of
<DvdOrder>
❑ Display attribute HowMuchbefore attribute FilmOrderNumber
A great many of the steps performed by the transform could have been achieved using an alternative technology For example, you could have used Source Code Style attributes with your serialization to generate the correct XML attribute and XML element name If you had known in advance that a consortium of suppliers was going to develop a standard, you could have written your classes to be
430
Chapter 12
Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 24serialized based on the standard The point was that you didn’t know and now one standard (yourlegacy standard) has to be converted into a newly adopted standard of the movie suppliers’ consortium.The worst thing you could do would be to change your working code and then force all users workingwith the application to upgrade It is vastly simpler to add an extra transformation step to address thenew standard.
The XSLT file that facilitates the transform is named ConvertLegacyToNewStandard.xslt A portion
of this file is implemented as follows:
In the previous snippet of XSLT, the following XSLT elements are used to facilitate the transformation:
❑ <xsl:template match=”FilmOrder”>— All operations in this templateXSLT element willtake place on the original document’s FilmOrdernode
❑ <xsl:element name=”DvdOrder”>— The element corresponding to the source document’sFilmOrderelement will be called DvdOrderin the destination document
❑ <xsl:attribute name=”HowMuch”>— An attribute named HowMuchwill be contained in thepreviously specified element The previously specified element is <DvdOrder> This attributeXSLT element for HowMuchcomes before the attributeXSLT element for FilmOrderNumber.This order was specified as part of your transform to adhere to the new standard
❑ <xsl:value-of select=’quantity’>— Retrieve the value of the source document’s
<quantity>element and place it in the destination document This instance of XSLT element,value-of, provides the value associated with attribute HowMuch
Two new XSLT elements have crept into your vocabulary: elementand attribute Both of these XSLTelements live up to their names Specifying the XSLT element named elementplaces an element in thedestination XML document Specifying the XSLT element named attributeplaces an attribute in thedestination XML document The XSLT transform found in ConvertLegacyToNewStandard.xsltis toolong to review completely When reading this file in its entirety, you should remember that this XSLT filecontains inline documentation to specify precisely what aspect of the transformation is being performed
at which location in the XSLT document For example, the following XML code comments inform youabout what the XSLT element attributeis about to do:
<! Make element ‘quantity’ attribute HowMuchNotice attribute HowMuch comes before attribute FilmOrderNumber >
<xsl:attribute name=”HowMuch”>
431
Using XML in Visual Basic 2005
Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 25<xsl:value-of select=’quantity’></xsl:value-of>
</xsl:attribute>
The previous example spanned several pages but contained just three lines of code This demonstratesthat there is more to XML than learning how to use it in Visual Basic and the NET Framework Amongother things, you also need a good understanding of XSLT, XPath, and XQuery
Other Classes and Interfaces in System.Xml.Xsl
We just took a good look at XSLT and the System.Xml.Xslnamespace, but there is a lot more to it thanthat The other classes and interfaces exposed by System.Xml.Xslnamespace include
❑ IXsltContextFunction— This interface accesses at runtime a given function defined in theXSLT style sheet
❑ IXsltContextVariable— This interface accesses at runtime a given variable defined in theXSLT style sheet
❑ XsltArgumentList— This class contains a list of arguments These arguments are XSLTparameters or XSLT extension objects The XsltArgumentListobject is used in conjunctionwith the Transformmethod of XslTransformand XslCompiledTransform
❑ XsltContext— This class contains the state of the XSLT processor This context informationallows XPath expressions to have their various components resolved (functions, parameters,and namespaces)
❑ XsltException, XsltCompileException— These classes contain the information pertaining
to an exception raised while transforming data XsltCompileExceptionis derived fromXsltException
ADO.NET
ADO.NET allows Visual Basic applications to generate XML documents and to use such documents toupdate persisted data ADO.NET natively represents its DataSet’s underlying datastore in XML.ADO.NET also allows SQL Server — specific XML support to be accessed In this chapter, your focus is
on those features of ADO.NET that allow the XML generated and consumed to be customized
ADO.NET is covered in detail in Chapter 11
The DataSetproperties and methods that are pertinent to XML include Namespace, Prefix, GetXml,GetXmlSchema, InferXmlSchema, ReadXml, ReadXmlSchema, WriteXml, and WriteXmlSchema Anexample of code that uses the GetXmlmethod is:
Dim adapter As New _
SqlDataAdapter(“SELECT ShipperID, CompanyName, Phone “ & _
“FROM Shippers”, _
“SERVER=localhost;UID=sa;PWD=sa;Database=Northwind;”)Dim ds As New DataSet
Trang 26The previous code uses the sample Northwinddatabase (which comes with SQL Server and MSDE) andretrieves all rows from the Shipperstable This table was selected because it contains only three rows
of data The XML returned by GetXmlis as follows (where signifies that <Table>elements wereremoved for the sake of brevity):
gen-is returned as an XML element, <Table> The data returned is contained in an XML element named forthe column in which the data resides (<ShipperID>, <CompanyName>, and <Phone>, respectively).The root element, <NewDataSet>, is just the default name of the DataSet This name could have beenchanged when the DataSetwas constructed by specifying the name as a parameter to the constructor:Dim ds As New DataSet(“WeNameTheDataSet”)
If the previous version of the constructor was executed, then the <NewDataSet>element would berenamed <WeNameTheDataSet> After the DataSethas been constructed, you can still set the propertyDataSetName, thus changing <NewDataSet>to a name such as <WeNameTheDataSetAgain>:
Using the previous SQL statement, the <ShipperID>element would become the <TheID>element The
<CompanyName>element would become <CName>and <Phone>would become <TelephoneNumber>.The column names can also be changed programmatically by using the Columnsproperty associatedwith the table in which the column resides An example of this follows, where the XML element
<TheID>is changed to <AnotherNewName>.ds.Tables(“WeNameTheTable”).Columns(“TheID”).ColumnName = “AnotherNewName”
433
Using XML in Visual Basic 2005
Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 27This XML could be transformed using System.Xml.Xsl This XML could be read as a stream
(XmlTextReader) or written as a stream (XmlTextWriter) The XML returned by ADO.NET could even
be deserialized and used to create an object or objects using XmlSerializer What is important is torecognize what ADO.NET-generated XML looks like If you know its format, then you can transform itinto whatever you like
ADO.NET and SQL Server 2000’s Built-In XML Features
Those interested in fully exploring the XML-specific features of SQL Server should take a look at
Professional SQL Server 2000 Programming (Wrox Press, ISBN 0764543792) However, since the content of
that book is not NET-specific, the next example will form a bridge between Professional SQL Server 2000
Programming and the NET Framework.
Two of the major XML-related features exposed by SQL Server are
❑ FOR XML— The FOR XMLclause of an SQLSELECTstatement allows a rowset to be returned as anXML document The XML document generated by a FOR XMLclause is highly customizable withrespect to the document hierarchy generated, per-column data transforms, representation ofbinary data, XML schema generated, and a variety of other XML nuances
❑ OPENXML— The OPENXMLextension to Transact-SQL allows a stored procedure call to manipulate
an XML document as a rowset Subsequently, this rowset can be used to perform a variety of tasks,such as SELECT, INSERT INTO, DELETE, and UPDATE
SQL Server’s support for OPENXMLis a matter of calling a stored procedure call A developer who canexecute a stored procedure call using Visual Basic in conjunction with ADO.NET can take full advantage
of SQL Server’s support for OPENXML FOR XMLqueries have a certain caveat when it comes to ADO.NET
To understand this caveat, consider the following FOR XMLquery:
SELECT ShipperID, CompanyName, Phone FROM Shippers FOR XML RAW
Using SQL Server’s Query Analyzer, this FOR XML RAWquery generated the following XML:
<row ShipperID=”1” CompanyName=”Speedy Express” Phone=”(503) 555-9831”/>
<row ShipperID=”2” CompanyName=”United Package” Phone=”(503) 555-3199”/>
<row ShipperID=”3” CompanyName=”Federal Shipping” Phone=”(503) 555-9931”/>
The same FOR XML RAWquery can be executed from ADO.NET as follows:
Dim adapter As New _
SqlDataAdapter(“SELECT ShipperID, CompanyName, Phone “ & _
“FROM Shippers FOR XML RAW”, _
“SERVER=localhost;UID=sa;PWD=sa;Database=Northwind;”)Dim ds As New DataSet
Trang 28The output from the previous code snippet demonstrates this caveat (where represents similar datanot shown for reasons of brevity):
as />and /<) The data returned in element <XML_F52E2B61-18A1-11d1-B105- 00805F49916B>
is not XML but is data contained in an XML document
To fully utilize FOR XMLqueries, the data must be accessible as XML The solution to this quandary is theExecuteXmlReadermethod of the SQLCommandclass When this method is called, an SQLCommandobject assumes that it is executed as a FOR XMLquery and returns the results of this query as anXmlReaderobject An example of this follows (again found in VBNetXML05):
Dim connection As New _SqlConnection(“SERVER=localhost;UID=sa;PWD=sa;Database=Northwind;”)Dim command As New _
SqlCommand(“SELECT ShipperID, CompanyName, Phone “ & _
“FROM Shippers FOR XML RAW”)Dim memStream As MemoryStream = New MemoryStreamDim xmlReader As New XmlTextReader(memStream)connection.Open()
command.Connection = connectionxmlReader = command.ExecuteXmlReader()
‘ Extract results from XMLReaderThe XmlReadercreated in this code is of type XmlTextReader, which derives from XmlReader TheXmlTextReaderis backed by a MemoryStream, hence it is an in-memory stream of XML that can be traversed using the methods and properties exposed by XmlTextReader Streaming XML generationand retrieval has been discussed earlier
Using the ExecuteXmlReadermethod of the SQLCommandclass, it is possible to retrieve the result ofFOR XMLqueries What makes FOR XMLstyle of queries so powerful is that it can configure the dataretrieved The three types of FOR XMLqueries support the following forms of XML customization:
❑ FOR XML RAW— This type of query returns each row of a result set inside an XML elementnamed <row> The data retrieved is contained as attributes of the <row>element The attributesare named for the column name or column alias in the FOR XML RAWquery
❑ FOR XML AUTO— By default, this type of query returns each row of a result set inside an XMLelement named for the table or table alias contained in the FOR XML AUTOquery The data
435
Using XML in Visual Basic 2005
Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 29retrieved is contained as attributes of this element The attributes are named for the columnname or column alias in the FOR XML AUTOquery By specifying FOR XML AUTO, ELEMENTSit ispossible to retrieve all data inside elements rather than inside attributes All data retrieved must
be in attribute or element form There is no mix-and-match capability
❑ FOR XML EXPLICIT— This form of the FOR XMLquery allows the precise XML type of each column returned to be specified The data associated with a column can be returned as anattribute or an element Specific XML types, such as CDATAand ID, can be associated with a column returned Even the level in the XML hierarchy in which data resides can be specifiedusing a FOR XML EXPLICITquery This style of query is fairly complicated to implement.FOR XMLqueries are flexible Using FOR XML EXPLICITand the dental database, it would be possible togenerate any form of XML medical prescription standard The decision that needs to be made is whereXML configuration takes place Using Visual Basic, a developer could use XmlTextReaderand
XmlTextWriterto create any style of XML document Using the XSLT language and an XSLT file, thesame level of configuration can be achieved SQL Server and, in particular, FOR XML EXPLICITallow the same level of XML customization, but this customization takes place at the SQL level and may even
be configured to stored procedure calls
XML and SQL Server 2005
As a representation for data, XML is ideal in that it is a self-describing data format that allows you toprovide your datasets as complex datatypes as well as providing order to your data SQL Server 2005embraces this direction
More and more developers are turning to XML as a means of data storage For instance, Microsoft Office allows documents to be saved and stored as XML documents As more and more products andsolutions are turning toward XML as a means of storage, this allows for a separation between the underlying data and the presentation aspect of what is being viewed XML is also being used as ameans of communicating datasets across platforms and across the enterprise The entire XML Web services story is a result of this new capability Simply said, XML is a powerful alternative to your datastorage solutions
Just remember that the power of using XML isn’t only about storing data as XML somewhere (whetherthat is XML files or not), but is also about the ability to quickly get at this XML data and to be able toquery the data that is retrieved
SQL Server 2005 makes a big leap toward XML in adding an XML datatype This allows you to unify therelational data aspects of the database and the new desires to work with XML data
FOR XMLhas also been expanded from within this latest edition of SQL Server This includes a new TYPEdirective which returns an XML datatype instance Also, from the Framework, NET 2.0 adds a newnamespace —System.Data.SqlXml— which allows you to easily work with the XML data that comesfrom SQL Server 2005 The SqlXmlobject is an XmlReader-derived type Another addition is the use ofthe SqlDataReaderobject’s GetXmlmethod
436
Chapter 12
Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 30Summar y
Ultimately, XML could be the underpinnings of electronic commerce, banking transactions, and dataexchange of almost every conceivable kind The beauty of XML is that it isolates data representationfrom data display Technologies, such as HTML, contain data that is tightly bound to its display format.XML does not suffer this limitation, yet at the same time has the readability of HTML Accordingly, the XML facilities available to a Visual Basic application are vast, and there are a large number of XML-related features, classes, and interfaces exposed by the NET Framework
In this chapter, you saw how to use System.Xml.Serialization.XmlSerializerto serialize classes.Source Code Style attributes were introduced in conjunction with serialization This style of attributesallows the customization of the XML serialized to be extended to the source code associated with a class What is important to remember about the direct of serialization classes is that a required change
in the XML format becomes a change in the underlying source code Developers should resist the temptation to rewrite the serialized classes in order to conform to some new XML data standard (such
as the prescription format endorsed by your consortium of pharmacies) Technologies, such as XSLT,exposed via the System.Xml.Querynamespace should be examined first as alternatives You saw how touse XSLT style sheets to transform XML data using the classes found in the System.Xml.Xslnamespace.The most useful classes and interfaces in the System.Xmlnamespace were reviewed, including thosethat support document-style XML access: XmlDocument, XmlNode, XmlElement, and XmlAttribute.The System.Xmlnamespace also contains classes and interfaces that support stream-style XML access:XmlReaderand XmlWriter
Finally, you looked at using XML with Microsoft’s SQL Server
437
Using XML in Visual Basic 2005
Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 31Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 32Security in the NET Framewor k 2.0
This chapter will cover the basics of security and cryptography We’ll begin with a brief discussion
of the NET Framework’s security architecture, because this will have an impact on the solutionsthat we may choose to implement
The NET Framework provides us with additional tools and functionality with regard to security
We now have the System.Security.Permissionsnamespace, which allows us to control codeaccess permissions along with role-based and identity permissions Through our code, we can control access to objects programmatically, as well as receive information on the current permis-sions of objects This security framework will assist us in finding out if we have permissions to runour code, instead of getting halfway through execution and having to deal with permission-basedexceptions In this chapter we will cover:
❑ Concepts and definitions
❑ Permissions
❑ Roles
❑ Principals
❑ Code access permissions
❑ Role based permissions
Trang 33❑ Secret key encryption
❑ Public key cryptography standard
❑ Digital signatures
❑ Certification
❑ Secure Sockets Layer communications
Let’s begin the chapter by taking a look at some security concepts and definitions
Security Concepts and Definitions
Before going on, let’s detail the different types of security that we will be illustrating in this chapter andhow they can relate to real scenarios
Related Concept in Security.Permissions Security Type Namespace or Utility Purpose
(e.g locking down of specific files)Security Policies Caspol.exeutility, Set up overall security policy for
PermView.exeutility a machine or user from an
operating system level
Cryptographic Strong name and Use of Public key infrastructure
assembly, generation, and CertificatesSignCode.exeutility
Programmatic Groups and permission sets For use in pieces of code that are
being called into Provides extrasecurity to prevent users of callingcode from violating security measuresimplemented by the program that arenot provided for on a machine level
As always, the code for this chapter is available for download from www.wrox.com, which you’ll need in order to follow along.
Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 34There are many approaches to providing security on our machines where our shared code is hosted
If multiple shared code applications are on one machine, each piece of shared code can get called from many front-end applications Each piece of shared code will have its own security requirements for accessing environment variables — such as the registry, the file system, and other items — on themachine that it is running on From an NTFS perspective, the administrator of our server can only lock down those items on the machine that are not required to be accessed from any piece of shared code running on it Therefore, some applications will want to have additional security built in to preventany calling code from doing things it is not supposed to do The machine administrator can further assistthe programmers by using the utilities provided with NET to establish additional machine and/or userpolicies that programs can implement As a further step along this line, the NET environment has given
us programmatic security through Code Access security, Role Based security, and Identity security As afinal security measure, we can use the cryptographic methods provided to require the use of certificates
in order to execute our code
Security in the NET infrastructure has some basic concepts that we will discuss here Code security is managed and accessed in the NET environment through the use of security policies Security policies have
a relationship that is fundamentally tied to either the machine that code is running on, or to particularusers under whose context the code is running To this end, any modifications to the policy are done either
at the machine or user level
We establish the security policy on a given set of code by associating it with an entity called a group
A group is created and managed within each of the machine- and user-based policies These group classifications are set up so that we can place code into categories We would want to establish new code groups when we are ready to categorize the pieces of code that would run on a machine, and assignthe permissions that users will have to access the code For instance, if we wanted to group all Internetapplications and then group all non-Internet applications together, we would establish two groups and associate each of our applications with its respective group Now that we’ve got the code separatedinto groups, we can define different permission sets for each group If we wanted to limit our Internetapplications’ access to the local file system, we could create a permission set that limits that access andassociates the Internet application group with the new permission set By default, the NET environmentgives us one code group named All Codethat is associated with the FullTrustpermission set
Permission sets are unique combinations of security configurations that determine what each user with access to a machine can do on that machine Each set determines what a user has access to, forinstance, whether they can read environment variables, the file system, or execute other portions ofcode Permission sets are maintained at the machine and user levels through the utility Caspol.exe.Through this utility, we can create our own permission sets, though there are seven permission sets thatship with the NET infrastructure that are also useful, as shown in the following table
Permission Set Explanation
FullTrust Allows full access to all resources — adds assembly
to a special list that has FullTrustaccessEverything Allows full access to everything covered by default
named permission sets, only differs from Trustin that the group does not get added to theFullTrustAssembly List
Full-Table continued on following page
441
Security in the NET Framework 2.0
Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 35Permission Set Explanation
SkipVerification Allows objects to bypass all security verificationInternet Grants default rights that are normal for Internet
applicationsLocalInternet Grants rights that are not as restricted as Internet,
but not full trust
Security that is used within the programming environment also makes use of permission sets Throughcode we can control access to files in a file system, environment variables, file dialogs, isolated storage,reflections, registry, sockets, and UI Isolated storage and virtual file systems are new operating systemlevel storage locations that can be used by programs and are governed by the machine security policies.These file systems keep a machine safe from file system intrusion by designating a regulated area for filestorage The main access to these items is controlled through code access permissions
Although many methods that we use in Visual Basic 2005 give an identifiable return value, the onlyreturn value that we will get from security methods is if the method fails If a security method succeeds,
it will not give a return value If it fails, it will return an exception object reflecting the specific error thatoccurred
Permissions in the
System.Security.Permissions Namespace
The System.Security.Permissionsnamespace is the namespace that we will use in our code to establish and use permissions to access many things such as the file system, environment variables, andthe registry within our programs The namespace controls access to both operating system level objects
as well as code objects In order to use the namespace in our project, we need to include the ImportsSystem.Security.Permissionsline with any of our other Importsstatements in our project Usingthis namespace gives us access to using the CodeAccessPermissionand PrincipalPermissionclassesfor using role-based permissions and also utilizing information supplied by Identitypermissions.CodeAccessPermissionis the main class that we will use as it controls access to the operating systemlevel objects our code needs in order to function Role-based permissions and Identitypermissionsgrant access to objects based on the identity that the user of the program that is running carries with them
In the following table, those classes that end with Attribute, such as
EnvironmentPermissionAttribute, are the classes that allow us to modify the security
level at which our code is allowed to interact with each respective object The attributes that we
can specify reflect either Assert, Deny, or PermitOnlypermissions
If permissions are asserted, we have full access to the object, while if we have specified Denypermissions
we are not allowed to access the object through our code If we have PermitOnlyaccess, only objectswithin our program’s already determined scope can be accessed, and we cannot add any more resources
442
Chapter 13
Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 36beyond that scope In our table, we also deal with security in regard to Software Publishers A SoftwarePublisher is a specific entity that is using a digital signature to identify itself in a Web-based application.The following is a table of the namespace members that apply to Windows Forms programming with anexplanation of each.
CodeAccessSecurityAttribute Specifies security access to objects such as the
registry and file systemDataProtectionPermission Controls ability to access data and memory This is
a new class in the NET Framework 2.0
DataProtectionPermissionAttribute Allows security actions to be added for data
pro-tections via codeEnvironmentPermission Controls ability to see and modify system and user
environment variablesEnvironmentPermissionAttribute Allows security actions for environment variables
to be added via codeFileDialogPermission Controls ability to open files via a file dialogFileDialogPermissionAttribute Allows security actions to be added for File
Dialogs via codeFileIOPermission Controls ability to read and write files in the file
systemFileIOPermissionAttribute Allows security actions to be added for file access
attempts via codeGacIdentityPermission Defines the identity permissions for files which
come from the Global Assembly Cache (GAC) This
is a new class in the NET Framework 2.0
GacIdentityPermissionAttribute Allows security actions to be added for files which
originate from the GACIsolatedStorageFilePermission Controls ability to access a private virtual file system
within the isolated storage area of an applicationIsolatedStorageFilePermission Allows security actions to be added for private
IsolatedStoragePermission Controls ability to access the isolated storage area
of an applicationIsolatedStoragePermission Allows security actions to be added for the isolated
KeyContainerPermission Controls ability to access key containers This is a
new class in the NET Framework 2.0
Table continued on following page
443
Security in the NET Framework 2.0
Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 37Class Description
KeyContainerPermissionAccess Defines the access rights for particular key
KeyContainerPermissionAccess Represents a collection of
KeyContainerPermissionAccess Represents the enumerators for
EntryEnumerator the objects contained in the
KeyContainerPermissionAccessEntryCollectionobject
KeyContainerPermissionAttribute Allows security actions to be added for key
containersPermissionSetAttribute Allows security actions to be added for a
permission setPrincipalPermission Controls the ability to make checks against an
active principalPrincipalPermissionAttribute Allows for checking against a specific user
Security principals are a user and role combinationused to establish security identity
PublisherIdentityPermission Allows for ability to access based on the identity of
a software publisherPublisherIdentityPermission Allows security actions to be added for a software
ReflectionPermission This controls the ability to access nonpublic
members of a given type ReflectionPermissionAttribute Allows for security actions to be added for public
and nonpublic members of a given typeRegistryPermission Controls the ability to access registry keys and
valuesRegistryPermissionAttribute Allows security actions to be added for registry
keys and valuesResourcePermissionBase Controls the ability to work with the code access
security permissionsResourcePermissionBaseEntry Allows you to define the smallest part of a code
access security permission setSecurityAttribute Controls which security attributes are representing
code, used to control the security when creating anassembly
SecurityPermission The set of security permission flags for use by
.NET; this collection is used when we want to specify a permission flag in our code
444
Chapter 13
Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 38Class Description
SecurityPermissionAttribute Allows security actions for the security permission
flagsStorePermission Controls ability to access stores which contain
X509 certificates This is a new class in the NETFramework 2.0
StorePermissionAttribute Allows security actions to be added for access
stores which contain X509 certificatesUIPermission Controls ability to access user interfaces and use
the windows clipboardUIPermissionAttribute Allows security actions to be added for UI
Interfaces and the use of the clipboard
Code Access Permissions
Code access permissions are controlled through the CodeAccessPermissionclass within theSystem.Securitynamespace, and its members make up the majority of the permissions we’ll use inour attempt to secure our code and operating environment The following is a table of the class methodsand an explanation of their use
RevertAll Reverses all previous assert, denyor
permit-onlymethodsRevertAssert Reverses all previous assert methods
RevertPermitOnly Reverses all previous permit-only methodsAssert Sets the permission to full access so that the
specific resource can be accessed even if the callerhasn’t been granted permission to access theresource
CheckAsset Checks the validity of accessing the asserted
resource through a permission object This methodcan be overridden
CheckDemand Checks the validity of accessing the demanded
resource through a permission object This methodcan be overridden
CheckDeny Checks the validity of accessing the denied
resource through a permission object This methodcan be overridden
Table continued on following page
445
Security in the NET Framework 2.0
Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 39Method Description
CheckPermitOnly Checks the validity of accessing permitted
resources through a permission object Thismethod can be overridden
Demand Returns whether or not all callers in the call chain
have been granted the permission to access theresource in a given manner
Equals Determines if a given object is the same instance of
the current objectFromXml Establishes a permission set given a specific XML
encoding This parameter is an XML encodingGetHashCode Returns a hash code associated with a given object
Intersect Returns the permissions two permission objects
have in commonIsSubsetOf Returns result of whether the current permission
object is a subset of a specified permissionPermitOnly Determines that only those resources within this
permission object can be accessed even if code hasbeen granted permission to other objects
ToString Returns a string representation of the current
per-mission objectToXml Creates an XML representation of the current per-
mission objectUnion Creates a permission that is the union of two per-
mission objects
Role-Based Permissions
Role-based permissions are permissions granted based on the user and the role that code is being called with Users are generally authenticated within the operating system platform and hold a SecurityIdentifier (SID) that is associated within a security context The SID can further be associated with a role,
or a group membership that is established within a security context The NET role functionality supportsthose users and roles associated within a security context and also has support for generic and customusers and roles through the concept of principals A principal is an object that holds the current caller credentials, which is termed the identity of the user Principals come in two types: Windows principals and non-Windows principals Windows-based Principal objects are objects that store the Windows SID
446
Chapter 13
Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 40information regarding the current user context associated with the code that is calling into the modulewhere we are using role-based permissions NonWindows Principals are principal objects that are createdprogrammatically via a custom login methodology which are made available to the current thread.
Role-based permissions are not set against objects within our environment like code access permissions.They are instead a permission that is checked within the context of the current user and role that a user is part of Within the System.Security.Permissionsnamespace, the concept of the principalsand the PrincipalPermissionclass of objects are used to establish and check permissions If a programmer passes the user and role information during a call as captured from a custom login, thePrincipalPermissionclass can be used to verify this information as well During the verification, ifthe user and role information is Null, then permission is granted, regardless of the user and role ThePrincipalPermissionclass does not grant access to objects, but has methods that determine if a callerhas been given permissions according to the current permission object through the Demandmethod If asecurity exception is generated then the user does not have sufficient permission
The following table lists the methods in the PrincipalPermissionclass and a description of each
Demand Returns whether or not all callers in the call chain
have been granted the permission to access theresource in a given manner
Equals Determines if a given object is the same instance of
the current objectFromXml Establishes a permission set given a specific XML
encodingGetHashCode Returns a hash code associated with a given object
Intersect Returns the permissions two permission objects
have in common specified in the parameterIsSubsetOf Returns the result of whether the current permission
object is a subset of a specified permissionIsUnrestricted Returns the result of whether the current permission
object is unrestrictedToString Returns a string representation of the current
permission object
permission objectUnion Creates a permission that is the union of two
permission objects
447
Security in the NET Framework 2.0
Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com