小秋的家

home

  BlogJava :: 首页 :: 联系 :: 聚合  :: 管理
  1 Posts :: 91 Stories :: 17 Comments :: 0 Trackbacks
IE中的XML DOM

当微软在IE 5.0中第一次加入对XML支持时,他们只是在MSXML ActiveX库(最初是为了在IE 4.0中解析Active Channels的组件)中实现XML的功能。最初的版本并没有打算公开使用,然而随着开发人员逐渐了解这个组件并尝试使用时,微软才意识到这个库的重要性,很快就在IE 4.01中发布了MSXML完全升级版本。

MSXML最初还只是IE的一个组件。直到2001年,微软发布了MSXML 3.0,这是一个通过其公司网站独立发布的产品。在2001年晚些时候,微软又发布了MSXML 4.0,并且将其更名为微软XML核心服务组件。MSXML从最初一个基本的、无校验功能的XML解析器,逐渐发展成一个功能强大的组件,能够校验XML文档,进行XSL转化,支持命名空间、XML的简单APISAX),以及W3C XPathXML Schema标准,并且每个新版本都在性能上有一定的提升。

为了在JavaScript中创建ActiveX对象,微软实现一个新的ActiveXObject类,该类用来实例化ActiveX对象。ActiveXObject类的构造函数包含一个字符串参数,该参数表示要创建的ActiveX对象的版本,在此指的就是XML文档的版本。第一个XML DOM ActiveX对象名为Microsoft.XmlDom,其创建方法如下所示:

var oXmlDom = new ActiveXObject("Microsoft.XmlDom");

这个新创建的XML DOM对象与其他DOM对象一样,可以用来遍历DOM树,操作DOM节点。

到本书截稿为止,MSXML DOM文档共有五个不同的版本,分别是:

Microsoft.XmlDom

MSXML2.DOMDocument

MSXML2.DOMDocument.3.0

MSXML2.DOMDocument.4.0

MSXML2.DOMDocument.5.0

MSXML是基于ActiveX的实现,因此只能够在Windows平台上使用。在Mac平台上的IE 5是不提供XML DOM支持的。

因为存在五个不同版本,而你总是会使用最新版,所以使用一个函数来判断浏览器所使用的版本是相当有用的。这样就可以确保使用最新的XML支持,获取最佳的性能。下面的函数createDocument()将使你能够创建正确的MSXML DOM文档。

function createDocument() {

    var aVersions = [ "MSXML2.DOMDocument.5.0",

       "MSXML2.DOMDocument.4.0","MSXML2.DOMDocument.3.0",

       "MSXML2.DOMDocument","Microsoft.XmlDom"

    ];

      for (var i = 0; i < aVersions.length; i++) {

         try {

             var oXmlDom = new ActiveXObject(aVersions[i]);

             return oXmlDom;

         } catch (oError) {

               // 不做任何处理

      }

    }

    throw new Error("MSXML is not installed.");

}

该函数遍历存放MSXML DOM文档的版本号的aVersions数组,从最新版本MSXML2.DOMDocument.5.0开始尝试创建DOM文档。如果成功创建对象,那么返回该对象且退出createDocument();否则try...catch语句将捕获所抛出的异常,并继续下一次循环,尝试下一个版本。如果MSXML DOM文档创建失败,那么抛出异常,说明MSXML未安装。由于该函数不是一个类,所以用法与其他函数类似,都将返回一个值:

var oXmlDom = createDocument();

使用createDocument()函数将确保程序使用最新的DOM文档。当创建了XML文档后,下一步就是载入XML数据。

1. IE中载入XML数据

MSXML支持两种载入XML的方法:load()loadXML()Load()方法从Web的指定位置载入一个XML文件。与XMLHttp一样,load()方法可以以同步或异步两种模式载入数据。默认情况下,load()方法采用异步模式;如果要采用同步模式,那么必须将MSXML对象的async属性设置为false,代码如下:

oXmlDom.async = false;

当采用异步模式时,MSXML对象公开了readyState属性,该属性和XMLHttpreadyState属性一样,包含五种状态。

此外,DOM文档支持onreadystatechange事件处理函数,可以监控readyState属性。因为异步模式是默认选项,因此将async属性设置为true是可选的:

oXmlDom.async = true;

oXmlDom.onreadystatechange = function () {

    if (oXmlDom.readyState == 4) {

       //document完全载入后,进行某些操作

    }

};

oXmlDom.load("myxml.xml");

本示例中,将把虚构的、名为myxml.xmlXML文档载入到XML DOM 文档中。当readyState值为4时,说明文档已经完全载入,则执行if语句中的代码。

第二种载入XML数据的方法是loadXML(),该方法与load()方法的主要区别在于从字符串载入XML,而不是根据指定的文件名载入XML。该字符串必须包含正确格式的XML,如下所示:

var sXml = "<root><person><name>Jeremy McPeak</name></person></root>";

oXmlDom.loadXML(sXml);

在此,oXmlDom文档将载入sXml变量中包含的XML数据。loadXML()方法不需要像load()方法那样检查readyState属性,也不需要设置async属性,因为该方法并不涉及服务器请求。

2. IE中遍历XML DOM文档

XML DOM文档的遍历与HTML DOM的遍历非常类似,因为它们都是节点层次的结构。节点树的最顶部是documentElement属性,包含文档的根元素。使用表4-1中所列出的属性,可以访问文档中任何元素或属性。

4-1 XML DOM属性

   

   

attributes

包含当前节点属性的数组

childNodes

包含子节点数组

firstChild

指向当前节点的第一个子节点

lastChild

指向当前节点的最后一个子节点

nextSibling

返回当前节点的下一个邻居节点

nodeName

返回当前节点的名字

nodeType

指定当前节点的XML DOM节点类型

nodeValue

包含当前节点的文本

ownerDocument

返回文档的根元素

parentNode

指向当前节点的父节点

previousSibling

返回当前节点的前一个邻居节点

text

返回当前节点的内容或当前节点及其子节点的文本(只有IE才支持的属性)

xml

以字符串返回当前节点及其子节点的XML(只有IE才支持的属性)

遍历DOM文档并获取数据,是一个很直观的过程。让我们看看下面的XML文档:

<?xml version="1.0" encoding="utf-8"?>

<books>

    <book isbn="0471777781">Professional Ajax</book>

    <book isbn="0764579088">Professional JavaScript for Web Developers</book>

    <book isbn="0764557599">Professional C#</book>

    <book isbn="1861002025">Professional Visual Basic 6 Databases</book>

</books>

这是一个简单的XML文档,包含一个根元素<books/>以及四个子元素<book/>。以该文档为例,我们可以研究DOM的细节。DOM树是基于节点之间的关系构造的。一个节点可能包含其他节点或者子节点。另一个节点可能与其他节点拥有相同的父节点,我们称之为邻居节点。

如果要获取文档中第一个<book/>元素,那么只需简单通过访问firstChild属性就可以达到目的:

var oRoot = oXmlDom.documentElement;

var oFirstBook = oRoot.firstChild;

documentElement赋给变量oRoot,可以节省程序空间和输入的内容,尽管这并不是必需的。使用firstChild属性可以引用根元素<books/>的第一个子元素<books/>的引用,并将其赋值给变量oFirstBook

使用childNodes集合也可以达到相同的目的:

var oFirstBook2 = oRoot.childNodes[0];

选择childNodes集合中的第一项将返回根节点的第一个子节点。因为childNodesJavaScript中的NodeList类型,所以使用length属性可以得到子节点的数量,如下:

var iChildren = oRoot.childNodes.length;

本示例中,因为文档元素有四个子节点,所以iChildren值为4

正如前面所述,节点可以有子节点,也就意味着它可以有父节点。通过parentNode属性可以选择当前节点的父节点:

var oParent = oFirstBook.parentNode;

在本小节前面已经提到变量oFirstBook,不过很快,它现在已经是文档中第一个<book/>元素,所以其parentNode属性就是指DOMdocumentElement属性,也就是<books/>元素。

如果当前节点是book元素,那么如何选择另一个book元素呢?因为<book/>元素有共同的父节点,所以它们互为邻居关系。通过nextSiblingpreviousSibling属性可以选择当前节点的临近节点。nextSibling属性指向下一个邻居,而previousSibling属性指向前一个邻居:

var oSecondBook = oFirstBook.nextSibling;

oFirstBook2 = oSecondBook.previousSibling;

这段代码引用第二个<book/>元素,并将其赋值给oSecondBook。通过oSecondBook邻居节点对变量oFirstBook2重新赋值,oFirstBook2的值不变。如果节点没有下一个邻居节点,那么nextSiblingnull。对于previousSibling也是同样的,如果当前节点没有前一个邻居节点,那么previousSibling也为null

现在我们知道了如何遍历文档结构,接下来要了解的是如何从树的节点获取数据。例如,使用text属性可以得到包含第三个<book/>元素的文本,代码如下:

var sText = oRoot.childNodes[2].text;

text属性(微软特有的属性)可以得到该节点包含的所有文本节点,该属性相当有用。如果没有text属性,访问文本节点必须:

var sText = oRoot.childNodes[2].firstChild.nodeValue;

这段代码与前面使用text属性的代码一样得到同样的结果。类似上一个例子,使用childNodes集合引用第三个<book/>元素,而使用firstChild指向<book/>元素的文本节点,因为文本节点在DOM中仍是一个节点。使用nodeValue属性获取当前节点的值,就可以获取文本。

这两个示例所产生的结果是相同的,然而使用text属性和使用文本节点的nodeValue属性之间存在一个主要的区别。text属性将得到包含当前元素及其子节点的所有文本节点的值,而nodeValue属性只能得到当前节点的值。它虽然是个有用的属性,但可能会返回比预期值更多的内容。例如,假设我们将XML文档修改成:

<?xml version="1.0" encoding="utf-8"?>

<books>

    <book isbn="0471777781">

        <title>Professional Ajax</title>

        <author>Nicholas C. Zakas, Jeremy McPeak, Joe Fawcett</author>

    </book>

    <book isbn="0764579088">Professional JavaScript for Web Developers</book>

    <book isbn="0764557599">Professional C#</book>

    <book isbn="1861002025">Professional Visual Basic 6 Databases</book>

</books>

新的XML文档在第一个<book/>元素中添加了两个新的子节点:<title/>元素(书名),<author/>元素(作者)。我们再一次使用text属性:

alert(oFirstChild.text);

代码中没有其他新的内容,我们可以看看图4-1中所显示的结果。

  4-1

请注意,这时我们将获得<title/><author/>元素的文本节点,并将其连接在一起。这就是textnodeValue的不同之处。nodeValue属性只能得到当前节点的值,而text属性则将得到包含当前节点及其子节点的所有文本节点。

MSXML还提供其他一些获取特定节点或数值的方法,最常用的方法是getAttribute()getElementsByTagName()

getAttribute()方法将接受一个包含属性名称的字符串型参数,并返回属性值。如果指定的属性不存在,那么返回的值为null。我们还将使用本小节前面提到的那个XML文档,请看下列代码:

var sAttribute = oFirstChild.getAttribute("isbn");

alert(sAttribute);

这段代码获取第一个<book/>元素的isbn属性值,并将其赋值给变量sAttribute然后使用Alert()方法显示该值。

getElementsByTagName()方法根据其参数所指定的名字,返回子元素的NodeList。该方法只搜索给定的节点中的元素,所以返回的NodeList不包含任何外部元素。例如:

var cBooks = oRoot.getElementsByTagName("book");

alert(cBooks.length);

这段代码获取文档中所有的<book/>元素,并将返回的NodeList赋值给变量cBooks。对于前面那个XML文档例子而言,警告框将显示找到的四个<book/>元素。如果要获取所有子节点,那么必须用“*”作为getElementsByTagName()方法的参数,其代码如下所示:

var cElements = oRoot.getElementsByTagName("*");

因为前面的XML文档例子中只包含<book/>元素,所以这段代码的结果与上一个示例相同。

3. IE中获取XML数据

要获取XML数据只需使用一个属性,即xml。该属性将对当前节点的XML数据进行序列化。序列化(serialization是将对象转换成简单的可存储或可传输格式的过程。xml属性将XML转换成字符串形式,包括完整的标签名称、属性和文本:

var sXml = oRoot.xml;

alert(sXml);

这段代码从文档元素开始序列化XML数据,并将其作为参数传递给alert()方法。下面就是部分已序列化的XML

<books><book isbn="0471777781">Professional Ajax</book></books>

已序列化的数据可以载入到另一个XML DOM对象,发送到服务器,或者传给另一个页面。通过xml属性返回的已序列化XML数据,取决于当前节点。如果是在documentElement节点使用xml属性,那么将返回整个文档的XML数据;如果只是在<book/>元素上使用它,那么将返回该<book/>元素所包含的XML数据。

xml属性是只读属性。如果希望往文档中添加元素,那么必须使用DOM方法来实现。

4. IE中操作DOM

现在为止,我们已经学习如何遍历DOM,从DOM中提取信息,将XML转换成字符串格式。接下来学习的是如何在DOM中添加、删除和替换节点。

l   创建节点

使用DOM方法可以创建多种不同的节点。第一种就是用createElement()方法创建的元素。向该方法传入一个参数,指明要创建的元素标签名称,并返回一个对XMLDOMElement的引用:

var oNewBook = oXmlDom.createElement("book");

oXmlDom.documentElement.appendChild(oNewBook);

这段代码创建一个新的<book/>元素,并通过appendChild()方法把它添加到documentElement中。appendChild()方法添加由其参数指定的新元素,并且将其作为最后一个子节点。但在该例子中,添加到该文档中的是一个空的<book/>元素,因而还需要为该元素添加一些文本:

var oNewBook = oXmlDom.createElement("book");

var oNewBookText = oXmlDom.createTextNode("Professional .NET 2.0 Generics");

oNewBook.appendChild(oNewBookText);

oXmlDom.documentElement.appendChild(oNewBook);

这段代码通过createTextNode()方法创建一个文本节点,并通过appendChild()方法把它添加到新创建的<book/>元素中。createTextNode()方法只有一个字符串参数,用来指定文本节点的值。

现在已经通过程序创建了新的<book/>元素,为其提供了一个文本节点,并将它添加到文档中。对于这个新元素而言,还需要像其他邻居节点一样,为其设置isbn属性。这很简单,只要通过setAttribute()方法就可以创建属性,该方法适用于所有元素节点。

var oNewBook = oXmlDom.createElement("book");

var oNewBookText = oXmlDom.createTextNode("Professional .NET 2.0 Generics");

oNewBook.appendChild(oNewBookText);

oNewBook.setAttribute("isbn","0764559885");

oXmlDom.documentElement.appendChild(oNewBook);

上面这段代码中,新添加的一行是用来创建isbn属性的,并将其值赋为0764559885setAttribute()方法有两个参数:第一个参数是属性名,第二个参数则是赋给该属性的值。对于向元素添加属性,IE还提供其他一些方法,不过它们实际上并不比setAttribute()更好用,而且还需要更多的编码。

l   删除、替换和插入节点

如果能够往文档中添加节点,那么同样意味着可以删除节点。removeChild()方法正是用来实现该功能的。该方法包含一个参数:要删除的节点。例如,要从文档中删除第一个<book/>元素,则可以使用以下代码:

var oRemovedChild = oRoot.removeChild(oRoot.firstChild);

removeChild()方法返回被删除的子节点,因而oRemoveChild变量将指向已删除的<book/>元素。当拥有对旧节点的引用时,就可以将其放置在文档的任何地方。

如果想用oRemovedChild指向的元素来替换第三个<book/>元素,那么可以通过replaceChild()方法来实现,该方法返回被替换的节点:

var oReplacedChild = oRoot.replaceChild(oRemovedChild, oRoot.childNodes[2]);

replaceChild()方法接受两个参数:新添加的节点和将被替换的节点。在这段代码中,将用oRemovedChild变量引用的节点替换第三个<book/>元素,而被替换节点的引用将存在oReplacedChild变量中。

由于oReplaceChild变量是被替换节点的引用,因而可以容易地将其插入到文档中。使用appendChild()方法可以该其添加到子节点列表的最后,也可以使用insertBefore()方法将该节点插入到某个节点之前:

oRoot.insertBefore(oReplacedChild, oRoot.lastChild);

这段代码将之前被替换的节点插入到最后一个<book/>元素的前面。lastChild属性的用法与firstChild选择第一个子节点非常相似,通过该属性可以获取最后一个子节点。insertBefore()方法接受两个参数:要插入的节点和表示插入点的节点(插入点在该节点之前)。该方法也将返回插入节点的值,但上述例子中并不需要。

如你所见,DOM是一个相当强大的接口,通过它可以实现数据的获取、删除和添加等操作。

5. IE中处理错误

XML数据的载入过程中,可能会由于不同的原因而抛出错误。例如,外部的XML文件找不到,或者XML的格式不正确。为了处理这些情况,MSXML提供了一个包含错误信息的parseError对象。对于每个由MSXML创建的XML DOM文档对象而言,该对象都是其所属的属性值之一。

我们可以通过parseError对象公开的与整数0进行比较的errorCode属性来检查错误。如果errorCode不等于0,则表示有错误发生。下面的例子故意设计出现一个错误。

var sXml = "<root><person><name>Jeremy McPeak</name></root>";

var oXmlDom = createDocument();

oXmlDom.loadXML(sXml);

if (oXmlDom.parseError.errorCode != 0) {

    alert("An Error Occurred: " + oXmlDom.parseError.reason);

} else {

    //XML载入成功后的操作

}

大家会注意到,在突出显示的代码行中,<person>元素是不完整的(没有相应的</person>标签)。由于要载入的XML的格式不正确,因此将产生一个错误。然后errorCode0进行比较,如果不相等(在本例中就不相等),那么将显示发生错误的警告。要实现该功能,可以使用parseError对象的reason属性来获取错误出现的原因。

parseError对象提供了以下属性,能够帮助你更好地了解错误:

errorCode:错误代码(长整型);

filePos:在文件中发生错误的位置(长整型);

line:包含错误的代码行的行号(长整型);

linePos:在特定行中发生错误的位置(长整型);

reason: 错误的原因(字符串型);

srcText: 发生错误的代码行内容(字符串型);

url: XML文档的URL(字符串型)。

尽管这些属性提供了每种错误的信息,但是应该使用哪个属性,则取决于你的需要。

errorCode属性可以是正数也可以是负数,只有当errorCode0时才表示没有错误发生。



Firefox中的XML DOM

现在我们来看看Firefox中的XML DOM实现,Firefox的开发人员采用更为标准的方法,将其作为JavaScript实现的一部分。Mozilla确保所有基于Gecko的浏览器的所有平台都支持XML DOM

Firefox中创建一个XML DOM,需要调用document.implementation对象的createDocument()方法。该方法接受三个参数:第一个参数是包含文档所使用的命名空间URI的字符串;第二个参数是包含文档根元素名称的字符串;第三个参数是要创建的文档类型(也称为doctype)。如果要创建空的DOM文档,则代码如下所示:

var oXmlDom = document.implementation.createDocument("", "", null);

前两个参数是空字符串,第三个参数为null,这样可以确保生成一个彻底的空文档。事实上,现在Firefox中并不提供针对文档类型的JavaScript支持,所以第三个参数总是为null。如果要创建包含文档元素的XML DOM,那么可以在第二个参数中指定标签名称:

var oXmlDom = document.implementation.createDocument("", "books", null);

这段代码创建了一个XML DOM,其documentElement<books/>。如果要创建包含指定命名空间的DOM,可以在第一个参数中指定命名空间URI

var oXmlDom = document.implementation.createDocument("http://www.site1.com",

       "books", null);

当在createDocument()方法中指定命名空间时, Firefox会自动附上前缀a0以表示命名空间URI

<a0:books xmlns:a0="http://www.site1.com" />

接着,你可以通过程序来填充XML文档,不过在一般情况下,还需要在空的XML DOM对象中载入现有的XML文档。

1. Firefox中载入XML数据

Firefox中,将XML载入XML DOM的方法和微软采用的方法大致相同,只存在一个显著区别:Firefox只支持load()方法。因此,在这两种浏览器中载入外部XML数据的代码是相同的:

oXmlDom.load("books.xml");

与微软的IE一样,Firefox同样实现了async属性,该属性的行为也与其一致:将async设置为false,表示以同步模式载入文档;否则,以异步模式载入文档。

FirefoxXML DOM实现和微软的XML DOM实现还存在另一个不同,即Firefox不支持readyState属性及onreadystatechange事件处理函数。在Firefox中,支持load事件和onload事件处理函数。在文档完全载入后将触发load事件:

oXmlDom.load("books.xml");

oXmlDom.onload = function () {

    //文档完全载入后的操作

};

正如前面所说,在FirefoxXML DOM实现中,并没有loadXML()方法,不过通过Firefox中的DOMParser类可以模拟loadXML()的行为。该类有一个名为parseFromString()的方法,用来载入字符串并解析成文档:

var sXml = "<root><person><name>Jeremy McPeak</name></person></root>";

var oParser = new DOMParser();

var oXmlDom = oParser.parseFromString(sXml,"text/xml");

在这段代码中,创建了一个XML字符串,并作为参数传递给DOMParserparseFromString()方法。parseFromString()方法的两个参数分别是XML字符串和数据的内容类型(一般设置为text/xml)parseFromString()方法返回XML DOM对象,因此这里得到的oXmlDom与第一个例子相同。

2. Firefox中获取XML数据

尽管存在这样那样的不同,但IEFirefox中用于获取文档中XML数据的大多数属性和方法是一致的。正如在IE中,可以使用documentElement属性来获取文档的根元素,例如:

var oRoot = oXmlDom.documentElement;

Firefox同样支持W3C标准属性,包括childNodesfirstChildlastChildnextSiblingnodeNamenodeTypenodeValueownerDocumentparentNodepreviousSibling。不幸的是,对于微软专有的textxml属性,Firefox并不支持,不过可以利用其他方法来模拟该属性的行为。

大家应该还记得,text属性返回了当前节点的内容,或者是当前节点及其子节点的内容。这不仅仅返回当前节点的文本,还有所有子节点的文本,因此要模拟该功能实现是十分容易的。下面这个简单的函数就能够完成该功能,该函数唯一的参数是一个节点:

function getText(oNode) {

    var sText = "";

    for (var i = 0; i < oNode.childNodes.length; i++) {

       if (oNode.childNodes[i].hasChildNodes()) {

           sText += getText(oNode.childNodes[i]);

       } else {

           sText += oNode.childNodes[i].nodeValue;

       }

    }

    return sText;

}

getText()函数中,sText变量用来保存获取的所有文本。接着对oNode的子节点使用for循环进行遍历,检查每个子节点是否包含子节点。如果有子节点,那么就将其childNode传给getText()函数,并进行同样的处理;如果没有子节点,那么将当前节点的nodeValue加到字符串中(对文本节点而言,这只是文本字符串)。处理了所有子节点后,该函数返回变量sText

IE中的xml属性将存放对当前节点包含的所有XML进行序列化的结果。在Firefox中,提供了一个名为XMLSerializer对象来完成这一功能。该对象提供一个使用JavaScript可访问的serializeToString()方法,使用该方法可以对XML数据进行序列化。

function serializeXml(oNode) {

    var oSerializer = new XMLSerializer();

    return oSerializer.serializeToString(oNode);

}

serializeXml()函数以XML节点作为参数,创建一个XMLSerializer对象,并将该节点传给serializeToString()方法。该方法将向调用者返回XML数据的字符串表示。

对于节点操作的DOM方法,FirefoxIE大致相同。参见“在IE中操作DOM”小节。

3. Firefox中处理错误

FirefoxIE的错误处理并不一样。当IE遇到错误时,它会填充parseError对象;而当Firefox遇到错误时,它会将包含错误信息的XML文档载入到XML DOM文档中。看下面的这个例子:

var sXml = "<root><person><name>Jeremy McPeak</name></root>";

var oParser = new DOMParser();

var oXmlDom = oParser.parseFromString(sXml,"text/xml");

 

if (oXmlDom.documentElement.tagName != "parsererror") {

    //没有错误发生,进行所需操作

} else {

    alert("An Error Occurred");

}

在突出显示的代码行中,你会发现其中将产生一个错误:XML字符串格式不正确(因为<person>元素不完整,没有相应的</person>元素)。当载入错误的XML时,XML DOM对象将会载入一个documentElement<parsererror/>的错误文档。我们可以通过检查documentElementtagName属性来很容易地确定是否发生错误。如果tagName属性不是parsererror,就可以确定没有发生任何错误。

在本例中,可能会生成如下所示的错误文档:

<parsererror xmlns="http://www.mozilla.org/newlayout/xml/parsererror.xml">XML

Parsing Error: mismatched tag. Expected: </person>.

Location: http://yoda/fooreader/test.htm

Line Number 1, Column 43:<sourcetext><root><person><name>Jeremy

McPeak</name></root>

------------------------------------------^</sourcetext></parsererror>

所有的错误信息都包含在错误文档的文本中。如果要通过程序使用这些错误信息,那么首先就要对其进行解析。最简单的方法是使用一个稍长的正则表达式:

var reError = />([\s\S]*?)Location:([\s\S]*?)Line Number (\d+), Column

    (\d+):<sourcetext>([\s\S]*?)(?:\-*\^)/;

该正则表达式将错误文档分为五个部分:错误消息、发生错误的文件名、行号、该行中发生错误的位置,以及发生错误的源代码。使用正则表达式对象的test()方法可以使用这些信息:

if (oXmlDom.firstChild.tagName != "parsererror") {

    //没有错误发生,进行所需操作

} else {

    var oXmlSerializer = new XMLSerializer();

    var sXmlError = oXmlSerializer.serializeToString(oXmlDom);

    var reError = />([\s\S]*?)Location:([\s\S]*?)Line Number (\d+), Column

       (\d+):<sourcetext>([\s\S]*?)(?:\-*\^)/;

    reError.test(sXmlError);

正则表达式捕获到的第一部分数据是错误消息,第二部分是文件名,第三部分是行号,第四部分是行内位置,第五部分是源码。你可以使用这些解析后的信息来创建自定义的错误消息:

var str = "An error occurred!!\n" +

    "Description: " + RegExp.$1 + "\n" +

    "File: " + RegExp.$2 + "\n" +

    "Line: " + RegExp.$3 + "\n" +

    "Line Position: " + RegExp.$4 + "\n" +

    "Source Code: " + RegExp.$5;

 

alert(str);

如果发生错误,那么alert()方法会以易于阅读的格式在警告框中来显示相关的错误信息。

posted on 2008-01-09 11:04 棋剑小秋 阅读(1076) 评论(0)  编辑  收藏 所属分类: DOM

只有注册用户登录后才能发表评论。


网站导航: