Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 40 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
40
Dung lượng
1,06 MB
Nội dung
or DTD. However, things are different when using the .NET System.Xml classes. Loading a combined schema or DTD and the XML data content (that is, an inline schema) or an XML document that references an external schema or DTD into any of the XML "storage" objects such as XmlDocument, XmlDataDocument, and XPathDocument does not automatically validate that document. And there is no property that we can set to make it do this. Instead, we load the document via an XmlTextReader object to which we have attached an XmlValidatingReader. The Load method of the XmlDocument and XmlDataDocument objects can accept an XmlValidatingReader as the single parameter instead of a file path and name. Meanwhile the constructor for the XPathDocument object can accept an XmlValdiatingReader as the single parameter. So all we have to do is set up our XmlValidatingReader and XmlTextReader combination, and then pass this to the Load method or the constructor function (depending on which document object we're creating). The document will then be validated as it is loaded: 'create XmlTextReader, load XML document and create Validator objXTReader = New XmlTextReader(strXMLPath) Dim objValidator As New XmlValidatingReader(objXTReader) objValidator.ValidationType = ValidationType.Schema 'use the validator/reader combination to create XPathDocument object Dim objXPathDoc As New XPathDocument(objValidator) 'use the validator/reader combination to create XmlDocument object Dim objXmlDoc As New XmlDocument() objXmlDoc.Load(objValidator) The XmlValidatingReader can also be used to validate XML held in a String. So we can validate XML that's already loaded into an object or application by simply extracting it as a String object (using the GetXml method w it h a DataSet object, or the OuterXml property to get a document fragment, for example) and applying the XmlValidatingReader to this. Validating XML in a DataSet Object Like the XML document objects, a DataSet does not automatically validate XML that you provide for the ReadXml method against any schema that is already in place within the DataSet or which is inline with the XML (that is, in the same document as the XML data content). In a DataSet, the schema is used solely to provide information about the intended structure of the data. It's not used for actual validation at all. When we load the schema, the DataSet uses it as a specification for the table names, column names, data types, etc. Then, when we load the XML data content, it arranges the data in the appropriate tables and columns as new data rows. If a value or element is encountered that doesn't match the schema, it is ignored and that particular column in the current data row is left empty. This makes sense, because the DataSet is designed to work with structured relational data, and so any superfluous content in the source file cannot be part of the correct data model. So, you should think of schemas in a DataSet as being a way to specify the data structure (rather than inferring the structure from the data, as happens if no schema is present). Don't think of this as a way of validating the data. A Document Validation Example We've provided an example page ' Validating XML documents with an XmlValidatingReader object' ( validating-xml.aspx) that demonstrates how you can validate an XML document. When first opened it displays a list of source documents that you can use in a drop-down list, and it performs validation against the selected document. As you can see from the screenshot, it reports no validation errors in a valid document: Note that you must run the page in a browser on the web server itself to be able to open the XML document and schema using the physical paths in the hyperlinks in the page. However, if you select the "well-formed but invalid" document, it reports a series of validation errors: In this case the XML document contains an extra child element within one of the <Books> elements, which is not permitted in the schema that we're using to validate it (you can view the document and the schema using the hyperlinks we provide in the page): <Books> <ISBN>1861003315</ISBN> <Title>Professional Outlook 2000 Programming</Title> <PublicationDate>1999-12-01T00:00:00</PublicationDate> <FirstName>Chris</FirstName> <MiddleInitial>J</MiddleInitial> <LastName>Burnham</LastName> </Books> The Code for the Validation Example The code that performs the validation is shown in the next listings. We start by creating the paths to the schema and XML document. In this example, the document name comes from the drop-down list named selXMLFile that is defined earlier in the page - the filename itself is the value attribute of the selected item: 'create physical path to sample files (in same folder as ASPX page) Dim strCurrentPath As String = Request.PhysicalPath Dim strXMLPath As String = Left(strCurrentPath, _ InStrRev(strCurrentPath, "\")) & selXMLFile.SelectedItem.Value Dim strSchemaPath As String = Left(strCurrentPath, _ InStrRev(strCurrentPath, "\")) & "booklist-schema.xsd" We then declare a variable to hold the number of validation errors we find. This is followed by code to create an XmlTextReader object, specifying the XML document as the source. We also display a hyperlink to this document: 'variable to count number of validation errors found Dim intValidErrors As Integer = 0 'create the new XmlTextReader object and load the XML document objXTReader = New XmlTextReader(strXMLPath) outXMLDoc.innerHTML = "Loaded file: <a href=""" & strXMLPath _ & """>" & strXMLPath & "</a><br />" Creating the XmlValidatingReader and Specifying the Schema The next step is to create our XmlValidatingReader object with the XmlTextReader as the source, and specify the validation type to suit our schema (we could, of course, have used Auto to automatically validate against any type of schema or DTD): 'create an XMLValidatingReader for this XmlTextReader Dim objValidator As New XmlValidatingReader(objXTReader) 'set the validation type to use an XSD schema objValidator.ValidationType = ValidationType.Schema Our schema is in a separate document and there is no link or reference to it in the XML document, so we need to specify which schema we want to use. We create a new XmlSchemaCollection, and add our schema to it using the Add method of the XmlSchemaCollection. Then we specify this collection as the Schemas property, and display a link to the schema: 'create a new XmlSchemaCollection Dim objSchemaCol As New XmlSchemaCollection() 'add the booklist-schema.xsd schema to it objSchemaCol.Add("", strSchemaPath) 'assign the schema collection to the XmlValidatingReader objValidator.Schemas.Add(objSchemaCol) outXMLDoc.innerHTML += "Validating against: <a href=""" _ & strSchemaPath & """>" & strSchemaPath & "</a>" Specifying the Validation Event Handler The XmlValidatingReader will raise an event whenever it encounters a validation error in the document, as the XmlTextReader reads it from our disk file. If we don't handle this event specifically, it will be raised to the default error handler. In our case, this is the Try Catch construct we include in our example page. However, it's often better to handle the validation events separately from other (usually fatal) errors such as the XML file not actually existing on disk. To specify our own event handler for the ValidationEventHandler event in Visual Basic we use the AddHandler method, and pass it the event we want to handle and a pointer to our handler routine (which is named ValidationError in this example): 'add the event handler for any validation errors found AddHandler objValidator.ValidationEventHandler, AddressOf ValidationError In C#, we can add the validation event handler using the following syntax: objValidator.ValidationEventHandler += new ValidationEventHandler(ValidationError); Reading the Document and Catching Parser Errors We are now ready to read the XML document from the disk file. In our case, we're only reading through to check for validation errors. In an application, you would have code here to perform whatever tasks you need against the XML, or alternatively use the XmlValidatingReader as the source for the Load method of an XmlDocument or XmlDataDocument object, or in the constructor for an XPathDocument object: Try 'iterate through the document reading and validating each element While objValidator.Read() 'use or display the XML content here as required End While Once validation is complete, we display a count of the number of errors found and close the reader object to release the disk file. If the document is not well-formed, or cannot be loaded for any other reason (such as it doesn't exist), a parser error occurs. So we include a statement in the Catch section that displays the error in this case: 'display count of errors found outXMLDoc.innerHTML += "Validation complete " & intValidErrors _ & " error(s) found" Catch objError As Exception 'will occur if there is a read error or the document cannot be parsed outXMLDoc.innerHTML += "Read/Parser error: " & objError.Message Finally 'must remember to always close the XmlTextReader after use objXTReader.Close() End Try That's all we need to do to validate the document. The remaining part of the code in this page is the event handler that we specified for the Validation event. We'll look at this next. The ValidationEvent Handler The XmlValidatingReader raises the Validation event whenever a validation error is discovered in the XML document, and we've specified that our event handler named ValidationError will be called when this event is raised. This event handler receives the usual reference to the object that raised the event, plus a ValidationEventArgs object containing information about the event. In the event handler, we first increment our error counter, and then check what kind of error it is by using the Severity property of the ValidationEventArgs object. We display a message describing the error, and the line number and character position if available (although these are generally included in the error message anyway): Public Sub ValidationError(objSender As Object, _ objArgs As ValidationEventArgs) 'event handler called when a validation error is found intValidErrors += 1 'increment count of errors 'check the severity of the error Dim strSeverity As String If objArgs.Severity = 0 Then strSeverity = "Error" If objArgs.Severity = 1 Then strSeverity = "Warning" 'display a message outXMLDoc.innerHTML += "Validation error: " & objArgs.Message _ & "<br /> Severity level: '" & strSeverity If objXTReader.LineNumber > 0 Then outXMLDoc.innerHTML += "Line: " & objXTReader.LineNumber _ & ", character: " & objXTReader.LinePosition End If End Sub We saw the validation error messages in the previous screenshot using a well-formed but invalid document. We've also provided an XML document that is not well-formed so that you can see the parser error that is raised in this case and trapped by our Try Catch construct. This also prevents the remainder of the document from being read: In this case, as you can verify if you try to open the XML document using the hyperlink, there is an illegal closing tag for one of the <Books> elements: <Books> <ISBN>1861003382</ISBN> <Title>Beginning Active Server Pages 3.0</Title> <PublicationDate>1999-12-01T00:00:00</PublicationDate> <FirstName>David</FirstName> <LastName>Sussman</LastName> </BBoook> We've also provided an option that tries to load a non-existent XML document, so you can see that the page traps this error successfully as well Creating and Editing XML Documents We've spent a lot of time looking at how we can read and write XML documents, access them in a range of ways, and validate the content against a schema or DTD. However, we haven't looked at how we can edit XML documents, or how we create new ones. The example page for this section, 'Creating and Editing the Content of XML Documents' ( edit-xml.aspx) fills out these gaps in our coverage. The example page loads an XML document named bookdetails.xml and demonstrates four different techniques we can use for editing and creating documents: Selecting a node, extracting the content, and deleting that node from the document Creating a new empty document and adding a declaration and comment to it Importing (that is, copying) a node from the original document into the new document Selecting, editing and inserting new nodes and content into the original document The next screenshot shows the page when you run it. You can see the four stages of the process, though the second and third are combined into one section of the output in the page: Note that you must run the page in a browser on the web server itself to be able to open the XML documents using the physical paths in the hyperlinks in the page. [...]... The machine.config file applies global default settings for all ASP.NET applications We will cover ASP.NET configuration in more detail in the next chapter Let's start by briefly looking at the ASP.NET bin directory as it relates to ASP.NET web applications Registering Components Rather than relying upon the system registry, ASP.NET uses a special directory, bin, to register components as part of an application... features in their own right, but are relevant for using IIS as a host for ASP.NET ASP.NET Web Applications - In this section, we will focus on two aspects of ASP.NET web applications; the \bin directory for compiled code deployment and the global.asax file format Application State Management - Here, we will look at the three options in ASP.NET for maintaining application state: Application, Session, and... process When it fails, it doesn't take down the host process, so one failure won't crash all our ASP.NET applications This is one of many new features provided by the CLR that ASP.NET takes advantage of An ASP.NET web application typically consists of three types of (user-created) resources, in addition to standard ASP.NET pages or web services These resource types are always found in the root of the application,... global.asax - This file is ASP.NET' s logical replacement for the ASP file global.asa It allows us to execute code for ASP.NET application-level events, and to set application-level variables web.config - Each web application can have its own ASP.NET configuration settings These settings, depending upon the security configuration of the system, can override settings found in ASP.NET' s machine.config The... our ASP.NET applications Web Applications and global.asax Classic ASP supported the concept of a web application This was primarily a collection of asp files plus the global.asa file ASP.NET expands upon this concept, but includes additional resources such as ASP.NET pages, web services, user controls, configuration data, global.asax, and several other files (both user-defined and defined by ASP.NET) ... automatically loaded by ASP.NET, and the components made available to our application There can only be one bin directory per ASP.NET application Local Server Access Not Required Deploying components in ASP.NET is simple As described above, local server access is not required and all we need is the ability to copy the compiled assembly to the bin directory Once it is there, ASP.NET and the CLR take... Internet Information Server documentation, as they do not relate to further discussions of ASP.NET in this chapter The only exception is mapping custom extensions to ASP.NET, which is covered later in the Advanced Topics section Users familiar with the Application Protection settings should note that these do not affect ASP.NET, since that runs in its own process, which is separate from IIS Please see the... configuration option in IIS Removing the application does not delete any associated files Now that we have had a quick overview of creating a web application in IIS, let's relate this back to ASP.NET ASP.NET Web Applications ASP.NET makes use of IIS web applications to identify distinct application domains Application domains are a feature of the Common Language Runtime (CLR) Each application domain is separate,... registration, and versioning - are no longer a problem in ASP.NET .NET Components As we mentioned earlier, in NET the term 'assemblies' is used to describe components - packaged units of reusable, compiled code - built with NET Unlike ASP, ASP.NET does not require local server access to register a component Instead, we can simply copy our assemblies to an ASP.NET bin directory using FTP, DAV, XCOPY, and so... we can configure our application - for example, how to set the Session state timeout using ASP.NET' s new configuration system IIS Web Roots and Applications An ASP.NET application consists of a collection of resources such as configuration information, global application files, compiled components, and other ASP.NET resources (pages, web services, and so on) These applications are defined using IIS . <Books> <ISBN> ;18 6 10 03 315 </ISBN> <Title> ;Professional Outlook 200 0 Programming</Title> <PublicationDate> ;19 99 -12 -01 T 00: 00: 00& lt;/PublicationDate> . <Books> <ISBN> ;18 6 10 03382</ISBN> <Title>Beginning Active Server Pages 3 .0& lt;/Title> <PublicationDate> ;19 99 -12 -01 T 00: 00: 00& lt;/PublicationDate> . we can use an XPath expression. In our example the expression is descendant::Book[ISBN=" ;18 6 10 03234"], which, when the current node is the root element of the document, selects the