一、创建XMLHttpRequest对象:
1.所有现代浏览器(IE7+、Firefox、Chrome、Safari 和 Opera)都有内建的 XMLHttpRequest 对象,(IE6及以下只有ActiveXObject对象,IE11不支持ActiveXObject对象),其创建 XMLHttpRequest 对象的语法:
var xmlhttp=new XMLHttpRequest();
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
<pre name="code" class="javascript">if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
二、XML解析:将XML文档或XML字符串解析成可通过 JavaScript 操作的XML DOM对象:
1、解析XML文档 成XML DOM对象:
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.open("GET","books.xml",false);
xmlhttp.send();
xmlDoc=xmlhttp.responseXML;
txt="<bookstore><book>";
txt=txt+"<title>Everyday Italian</title>";
txt=txt+"<author>Giada De Laurentiis</author>";
txt=txt+"<year>2005</year>";
txt=txt+"</book></bookstore>";
if (window.DOMParser)
{
parser=new DOMParser();
xmlDoc=parser.parseFromString(txt,"text/xml");
}
else // Internet Explorer
{
xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
xmlDoc.async=false;
xmlDoc.loadXML(txt);
}
三、XML跨域访问;
出于安全方面的原因,现代的浏览器不允许跨域的访问。
这意味着,网页以及它试图加载的 XML 文件,都必须位于相同的服务器上。
XML DOM(XML Document Object Model)定义了访问和操作 XML 文档的标准方法,XML DOM 把 XML 文档作为树结构来查看。
1.加载一个XML文档(跨浏览器实例)
<?xml version="1.0" encoding="utf-8"?>
<bookstore>
<!--记录书本的信息-->
<book Type="必修课" ISBN="7-111-19149-2">
<title>数据结构</title>
<author>严蔚敏</author>
<price>30.00</price>
</book>
<book Type="必修课" ISBN="7-111-19149-3">
<title>路由型与交换型互联网基础</title>
<author>程庆梅</author>
<price>27.00</price>
</book>
<book Type="必修课" ISBN="7-111-19149-4">
<title>计算机硬件技术基础</title>
<author>李继灿</author>
<price>25.00</price>
</book>
<book Type="必修课" ISBN="7-111-19149-5">
<title>软件质量保证与管理</title>
<author>朱少民</author>
<price>39.00</price>
</book>
<book Type="必修课" ISBN="7-111-19149-6">
<title>算法设计与分析</title>
<author>王红梅</author>
<price>23.00</price>
</book>
<book Type="选修课" ISBN="7-111-19149-1">
<title>计算机操作系统</title>
<author>7-111-19149-1</author>
<price>28</price>
</book>
</bookstore>
public class BookModel
{
public BookModel()
{ }
/// <summary>
/// 所对应的课程类型
/// </summary>
private string bookType;
public string BookType
{
get { return bookType; }
set { bookType = value; }
}
/// <summary>
/// 书所对应的ISBN号
/// </summary>
private string bookISBN;
public string BookISBN
{
get { return bookISBN; }
set { bookISBN = value; }
}
/// <summary>
/// 书名
/// </summary>
private string bookName;
public string BookName
{
get { return bookName; }
set { bookName = value; }
}
/// <summary>
/// 作者
/// </summary>
private string bookAuthor;
public string BookAuthor
{
get { return bookAuthor; }
set { bookAuthor = value; }
}
/// <summary>
/// 价格
/// </summary>
private double bookPrice;
public double BookPrice
{
get { return bookPrice; }
set { bookPrice = value; }
}
}
XmlDocument doc = new XmlDocument();
doc.Load(@"..\..\Book.xml");
//XmlDocument doc = new XmlDocument();
//doc.Load(@"..\..\Book.xml");
XmlDocument xmlDoc = new XmlDocument();
XmlReaderSettings settings = new XmlReaderSettings();
settings.IgnoreComments = true;//忽略文档里面的注释
XmlReader reader = XmlReader.Create(@"..\..\Book.xml", settings);
xmlDoc.Load(reader);
reader.Close();
// 得到根节点bookstore
XmlNode xn = xmlDoc.SelectSingleNode("bookstore");
// 得到根节点的所有子节点
XmlNodeList xnl = xn.ChildNodes;
List<BookModel> bookModeList = new List<BookModel>();
foreach (XmlNode xn1 in xnl)
{
BookModel bookModel = new BookModel();
// 将节点转换为元素,便于得到节点的属性值
XmlElement xe = (XmlElement)xn1;
// 得到Type和ISBN两个属性的属性值
bookModel.BookISBN = xe.GetAttribute("ISBN").ToString();
bookModel.BookType = xe.GetAttribute("Type").ToString();
// 得到Book节点的所有子节点
XmlNodeList xnl0 = xe.ChildNodes;
bookModel.BookName = xnl0.Item(0).InnerText;
bookModel.BookAuthor = xnl0.Item(1).InnerText;
bookModel.BookPrice = Convert.ToDouble(xnl0.Item(2).InnerText);
bookModeList.Add(bookModel);
}
//XmlDocument doc = new XmlDocument();
//doc.Load(@"..\..\Book.xml");
XmlDocument xmlDoc = new XmlDocument();
XmlReaderSettings settings = new XmlReaderSettings();
settings.IgnoreComments = true;//忽略文档里面的注释
XmlReader reader = XmlReader.Create(@"..\..\Book.xml", settings);
xmlDoc.Load(reader);
reader.Close();
// 得到根节点bookstore
XmlNode xn = xmlDoc.SelectSingleNode("bookstore");
//创建一个结点,并设置结点的属性:
XmlElement xelKey = xmlDoc.CreateElement("book");
//为结点添加属性
XmlAttribute xelType = xmlDoc.CreateAttribute("Type");
xelType.InnerText = "testy";
xelKey.SetAttributeNode(xelType);
<pre class="csharp" name="code"> XmlTextReader reader = new XmlTextReader(@"..\..\Book.xml");
List<BookModel> modelList = new List<BookModel>();
BookModel model = new BookModel();
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Element)
{
if (reader.Name == "book")
{
model.BookType = reader.GetAttribute(0);
model.BookISBN = reader.GetAttribute(1);
}
if (reader.Name == "title")
{
model.BookName = reader.ReadElementString().Trim();
}
if (reader.Name == "author")
{
model.BookAuthor = reader.ReadElementString().Trim();
}
if (reader.Name == "price")
{
model.BookPrice = Convert.ToDouble(reader.ReadElementString().Trim());
}
}
if (reader.NodeType == XmlNodeType.EndElement)
{
modelList.Add(model);
model = new BookModel();
}
}
//创建结点的子结点: XmlElement xelAuthor = xmlDoc.CreateElement("author"); xelAuthor.InnerText = "testAuthor"; //将子节点附加到结点中 xelKey.AppendChild(xelAuthor); //最后把book结点挂接在根结点上,并保存整个文件: xn.AppendChild(xelKey); xmlDoc.Save(@"..\..\Book.xml");
XmlDocument doc = new XmlDocument();
doc.LoadXml("<bookstore></bookstore>");//用这句话,会把以前的数据全部覆盖掉,只有你增加的数据,直接把根结点选择出来了,后面不用SelectSingleNode方法选择根结点,直接创建结点即可,代码同上
1.3、删除一个节点:
//获取xml文档对象的根XmlElement.
XmlElement xe = xmlDoc.DocumentElement;
string strPath = string.Format("/bookstore/book[@ISBN=\"{0}\"]", "7-111-19149-3");
//selectSingleNode 根据XPath表达式,获得符合条件的第一个节点.
XmlElement selectXe = (XmlElement)xe.SelectSingleNode(strPath);
//用查找到的结点的父节点去删除找到的结点
selectXe.ParentNode.RemoveChild(selectXe);
xmlDoc.Save(@"..\..\Book.xml");
XmlElement xe = xmlDoc.DocumentElement; // DocumentElement 获取xml文档对象的根XmlElement.
string strPath = string.Format("/bookstore/book[@ISBN=\"{0}\"]", "7-111-19149-3");
XmlElement selectXe = (XmlElement)xe.SelectSingleNode(strPath); //selectSingleNode 根据XPath表达式,获得符合条件的第一个节点.
selectXe.SetAttribute("Type", "选修课");//也可以通过SetAttribute来增加一个属性
selectXe.GetElementsByTagName("title").Item(0).InnerText = "美术";
selectXe.GetElementsByTagName("author").Item(0).InnerText = "test";
selectXe.GetElementsByTagName("price").Item(0).InnerText = "21.00";
xmlDoc.Save(@"..\..\Book.xml");
XmlTextReader reader = new XmlTextReader(@"..\..\Book.xml");
List<BookModel> modelList = new List<BookModel>();
BookModel model = new BookModel();
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Element)
{
if (reader.Name == "book")
{
model.BookType = reader.GetAttribute(0);
model.BookISBN = reader.GetAttribute(1);
}
if (reader.Name == "title")
{
model.BookName = reader.ReadElementString().Trim();
}
if (reader.Name == "author")
{
model.BookAuthor = reader.ReadElementString().Trim();
}
if (reader.Name == "price")
{
model.BookPrice = Convert.ToDouble(reader.ReadElementString().Trim());
}
}
if (reader.NodeType == XmlNodeType.EndElement)
{
modelList.Add(model);
model = new BookModel();
}
}
关键是读取属性的时候,你要先知道哪一个结点具有几个属性,然后通过GetAttribute方法来读取.读取属性还可以用另外一种方法,就是用MoveToAttribute方法.可参见下面的代码:
if (reader.Name == "book")
{
for (int i = 0; i < reader.AttributeCount; i++)
{
reader.MoveToAttribute(i);
string str = "属性:" + reader.Name + "=" + reader.Value;
}
model.BookType = reader.GetAttribute(0);
model.BookISBN = reader.GetAttribute(1);
}
XmlTextWriter myXmlTextWriter = new XmlTextWriter(@"..\..\Book1.xml", null);
//使用 Formatting 属性指定希望将 XML 设定为何种格式。 这样,子元素就可以通过使用 Indentation 和 IndentChar 属性来缩进。
myXmlTextWriter.Formatting = Formatting.Indented;
XmlTextWriter myXmlTextWriter = new XmlTextWriter(@"..\..\Book1.xml", null);
//使用 Formatting 属性指定希望将 XML 设定为何种格式。 这样,子元素就可以通过使用 Indentation 和 IndentChar 属性来缩进。
myXmlTextWriter.Formatting = Formatting.Indented;
myXmlTextWriter.WriteStartDocument(false);
myXmlTextWriter.WriteStartElement("bookstore");
myXmlTextWriter.WriteComment("记录书本的信息");
myXmlTextWriter.WriteStartElement("book");
myXmlTextWriter.WriteAttributeString("Type", "选修课");
myXmlTextWriter.WriteAttributeString("ISBN", "111111111");
myXmlTextWriter.WriteElementString("author", "张三");
myXmlTextWriter.WriteElementString("title", "职业生涯规划");
myXmlTextWriter.WriteElementString("price", "16.00");
myXmlTextWriter.WriteEndElement();
myXmlTextWriter.WriteEndElement();
myXmlTextWriter.Flush();
myXmlTextWriter.Close();
3.1、读取所有数据:
XElement xe = XElement.Load(@"..\..\Book.xml");
IEnumerable<XElement> elements = from ele in xe.Elements("book")
select ele;
showInfoByElements(elements);
XElement xe = XElement.Load(@"..\..\Book.xml");
XElement record = new XElement(
new XElement("book", new XAttribute("Type", "选修课"),
new XAttribute("ISBN", "7-111-19149-1"),
new XElement("title", "计算机操作系统"),
new XElement("Author", "test"),
new XElement("Price", 24.00))
);
xe.Add(record);
xe.Save(@"..\..\Book.xml");
XElement xe = XElement.Load(@"..\..\Book.xml");
IEnumerable<XElement> elements = from ele in xe.Elements("book")
where (string)ele.Attribute("ISBN") == "7-111-19149-6"
select ele;
if (elements.Count() > 0)
elements.First().Remove();
xe.Save(@"..\..\Book.xml");
XElement xe = XElement.Load(@"..\..\Book.xml");
IEnumerable<XElement> elements = from ele in xe.Elements("book")
select ele;
if (elements.Count() > 0)
elements.Remove();
xe.Save(@"..\..\Book.xml");
XElement xe = XElement.Load(@"..\..\Book.xml");
IEnumerable<XElement> elements = from ele in xe.Elements("book")
where (string)ele.Attribute("ISBN") == "7-111-19149-6"
select ele;
if (elements.Count() > 0)
{
XElement first = elements.First();
first.SetAttributeValue("Type", "选修课");
first.ReplaceNodes(
new XElement("title","1111"),
new XElement("Author","2222"),
new XElement("Price",23.00)
);
}
xe.Save(@"..\..\Book.xml");
•XPath 包含一个标准函数库
•XPath 是 XSLT 中的主要元素
•XPath 是一个 W3C 标准
<bookstore> (文档节点)
<author>J K. Rowling</author> (元素节点)
lang="en" (属性节点)
J K. Rowling
"en"
<?xml version="1.0" encoding="ISO-8859-1"?>
<bookstore>
<book>
<title lang="eng">Harry Potter</title>
<price>29.99</price>
</book>
<book>
<title lang="eng">Learning XML</title>
<price>39.95</price>
</book>
</bookstore>
表达式 | 描述 |
---|---|
nodename | 选取此节点的所有子节点。 |
/ | 从根节点选取。 |
// | 从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置。 |
. | 选取当前节点。 |
.. | 选取当前节点的父节点。 |
@ | 选取属性。 |
路径表达式 | 结果 |
---|---|
bookstore | 选取 bookstore 元素的所有子节点。 |
/bookstore | 选取根元素 bookstore。 注释:假如路径起始于正斜杠( / ),则此路径始终代表到某元素的绝对路径! |
bookstore/book | 选取属于 bookstore 的子元素的所有 book 元素。 |
//book | 选取所有 book 子元素,而不管它们在文档中的位置。 |
bookstore//book | 选择属于 bookstore 元素的后代的所有 book 元素,而不管它们位于 bookstore 之下的什么位置。 |
//@lang | 选取名为 lang 的所有属性。 |
路径表达式 | 结果 |
---|---|
/bookstore/book[1] | 选取属于 bookstore 子元素的第一个 book 元素。 |
/bookstore/book[last()] | 选取属于 bookstore 子元素的最后一个 book 元素。 |
/bookstore/book[last()-1] | 选取属于 bookstore 子元素的倒数第二个 book 元素。 |
/bookstore/book[position()<3] | 选取最前面的两个属于 bookstore 元素的子元素的 book 元素。 |
//title[@lang] | 选取所有拥有名为 lang 的属性的 title 元素。 |
//title[@lang='eng'] | 选取所有 title 元素,且这些元素拥有值为 eng 的 lang 属性。 |
/bookstore/book[price>35.00] | 选取 bookstore 元素的所有 book 元素,且其中的 price 元素的值须大于 35.00。 |
/bookstore/book[price>35.00]/title | 选取 bookstore 元素中的 book 元素的所有 title 元素,且其中的 price 元素的值须大于 35.00。 |
通配符 | 描述 |
---|---|
* | 匹配任何元素节点。 |
@* | 匹配任何属性节点。 |
node() | 匹配任何类型的节点。 |
路径表达式 | 结果 |
---|---|
/bookstore/* | 选取 bookstore 元素的所有子元素。 |
//* | 选取文档中的所有元素。 |
//title[@*] | 选取所有带有属性的 title 元素。 |
路径表达式 | 结果 |
---|---|
//book/title | //book/price | 选取 book 元素的所有 title 和 price 元素。 |
//title | //price | 选取文档中的所有 title 和 price 元素。 |
/bookstore/book/title | //price | 选取属于 bookstore 元素的 book 元素的所有 title 元素,以及文档中所有的 price 元素。 |
轴名称 | 结果 |
---|---|
ancestor | 选取当前节点的所有先辈(父、祖父等)。 |
ancestor-or-self | 选取当前节点的所有先辈(父、祖父等)以及当前节点本身。 |
attribute | 选取当前节点的所有属性。 |
child | 选取当前节点的所有子元素。 |
descendant | 选取当前节点的所有后代元素(子、孙等)。 |
descendant-or-self | 选取当前节点的所有后代元素(子、孙等)以及当前节点本身。 |
following | 选取文档中当前节点的结束标签之后的所有节点。 |
namespace | 选取当前节点的所有命名空间节点。 |
parent | 选取当前节点的父节点。 |
preceding | 选取文档中当前节点的开始标签之前的所有节点。 |
preceding-sibling | 选取当前节点之前的所有同级节点。 |
self | 选取当前节点。 |
例子 | 结果 |
---|---|
child::book | 选取所有属于当前节点的子元素的 book 节点。 |
attribute::lang | 选取当前节点的 lang 属性。 |
child::* | 选取当前节点的所有子元素。 |
attribute::* | 选取当前节点的所有属性。 |
child::text() | 选取当前节点的所有文本子节点。 |
child::node() | 选取当前节点的所有子节点。 |
descendant::book | 选取当前节点的所有 book 后代。 |
ancestor::book | 选择当前节点的所有 book 先辈。 |
ancestor-or-self::book | 选取当前节点的所有 book 先辈以及当前节点(如果此节点是 book 节点) |
child::*/child::price | 选取当前节点的所有 price 孙节点。 |
运算符 | 描述 | 实例 | 返回值 |
---|---|---|---|
| | 计算两个节点集 | //book | //cd | 返回所有拥有 book 和 cd 元素的节点集 |
+ | 加法 | 6 + 4 | 10 |
- | 减法 | 6 - 4 | 2 |
* | 乘法 | 6 * 4 | 24 |
div | 除法 | 8 div 4 | 2 |
= | 等于 | price=9.80 | 如果 price 是 9.80,则返回 true。 如果 price 是 9.90,则返回 false。 |
!= | 不等于 | price!=9.80 | 如果 price 是 9.90,则返回 true。 如果 price 是 9.80,则返回 false。 |
< | 小于 | price<9.80 | 如果 price 是 9.00,则返回 true。 如果 price 是 9.90,则返回 false。 |
<= | 小于或等于 | price<=9.80 | 如果 price 是 9.00,则返回 true。 如果 price 是 9.90,则返回 false。 |
> | 大于 | price>9.80 | 如果 price 是 9.90,则返回 true。 如果 price 是 9.80,则返回 false。 |
>= | 大于或等于 | price>=9.80 | 如果 price 是 9.90,则返回 true。 如果 price 是 9.70,则返回 false。 |
or | 或 | price=9.80 or price=9.70 | 如果 price 是 9.80,则返回 true。 如果 price 是 9.50,则返回 false。 |
and | 与 | price>9.00 and price<9.90 | 如果 price 是 9.80,则返回 true。 如果 price 是 8.50,则返回 false。 |
mod | 计算除法的余数 | 5 mod 2 | 1 |
HTML 使用预先定义的标签,标签的意义很容易被理解。
HTML 元素中的 <table> 元素定义表格 - 并且浏览器清楚如何显示它。
向 HTML 元素添加样式是很容易的。通过 CSS,很容易告知浏览器用特定的字体或颜色显示一个元素。
XSL = XML 样式表
XML 不使用预先定义的标签(我们可以使用任何喜欢的标签名),并且这些标签的意义并不都那么容易被理解。
<table> 元素意味着一个 HTML 表格,一件家具,或是别的什么东西 - 浏览器不清楚如何显示它。
XSL 可描述如何来显示 XML 文档!
XSL包含三部分:
XSLT:一种用于转换 XML 文档的语言。Mozilla 含有用于 XML 解析的 Expat,并支持 XML + CSS。Mozilla 同样支持命名空间。
Mozilla 可执行 XSLT。
从版本 8 开始,Netscape 就开始使用 Mozilla 引擎,所以它对 XML / XSLT 的支持与Mozilla是相同的。
从版本 9 开始,Opera 已开始支持 XML 和 XSLT(以及 CSS)。版本 8 仅支持 XML + CSS。
从版本 6 开始,Internet Explorer 已开始 XML、命名空间、CSS、XSLT 以及 XPath。
<?xml version="1.0" encoding="ISO-8859-1"?>
<catalog>
<cd>
<title>Empire Burlesque</title>
<artist>Bob Dylan</artist>
<country>USA</country>
<company>Columbia</company>
<price>10.90</price>
<year>1985</year>
</cd>
.
.
.
</catalog>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<h2>My CD Collection</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th align="left">Title</th>
<th align="left">Artist</th>
</tr>
<xsl:for-each select="catalog/cd">
<tr>
<td><xsl:value-of select="title"/></td>
<td><xsl:value-of select="artist"/></td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
<?xml version="1.0" encoding="ISO-8859-1"?>
<strong><?xml-stylesheet type="text/xsl" href="cdcatalog.xsl"?></strong>
<catalog>
<cd>
<title>Empire Burlesque</title>
<artist>Bob Dylan</artist>
<country>USA</country>
<company>Columbia</company>
<price>10.90</price>
<year>1985</year>
</cd>
.
.
.
</catalog>
4.XSL的 <xsl:template>元素:
4.2 由于 XSL 样式表本身也是一个 XML 文档,因此它总是由 XML 声明起始:<?xml version="1.0" encoding="ISO-8859-1"?>
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<h2>My CD Collection</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th>Title</th>
<th>Artist</th>
</tr>
<xsl:for-each select="catalog/cd">
<xsl:sort select="artist"/>
<tr>
<td><xsl:value-of select="title"/></td>
<td><xsl:value-of select="artist"/></td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<h2>My CD Collection</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th>Title</th>
<th>Artist</th>
</tr>
<xsl:for-each select="catalog/cd">
<xsl:if test="price > 10">
<tr>
<td><xsl:value-of select="title"/></td>
<td><xsl:value-of select="artist"/></td>
</tr>
</xsl:if>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
必选的 test 属性的值包含了需要求值的表达式。
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<h2>My CD Collection</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th>Title</th>
<th>Artist</th>
</tr>
<xsl:for-each select="catalog/cd">
<tr>
<td><xsl:value-of select="title"/></td>
<xsl:choose>
<xsl:when test="price > 10">
<td bgcolor="#ff00ff">
<xsl:value-of select="artist"/></td>
</xsl:when>
<xsl:otherwise>
<td><xsl:value-of select="artist"/></td>
</xsl:otherwise>
</xsl:choose>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<h2>My CD Collection</h2>
<xsl:apply-templates/>
</body>
</html>
</xsl:template>
<xsl:template match="cd">
<p>
<xsl:apply-templates select="title"/>
<xsl:apply-templates select="artist"/>
</p>
</xsl:template>
<xsl:template match="title">
Title: <span style="color:#ff0000">
<xsl:value-of select="."/></span>
<br />
</xsl:template>
<xsl:template match="artist">
Artist: <span style="color:#00ff00">
<xsl:value-of select="."/></span>
<br />
</xsl:template>
</xsl:stylesheet>
更通用的方法是使用 JavaScript 来完成转换。通过使用 JavaScript,我们可以:
•进行浏览器确认测试
•根据浏览器和使用者的需求来使用不同的样式表
<?xml version="1.0" encoding="ISO-8859-1"?>
<catalog>
<cd>
<title>Empire Burlesque</title>
<artist>Bob Dylan</artist>
<country>USA</country>
<company>Columbia</company>
<price>10.90</price>
<year>1985</year>
</cd>
.
.
.
</catalog> 请注意,这个 XML 文件没有包含对 XSL 文件的引用。
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<h2>My CD Collection</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th align="left">Title</th>
<th align="left">Artist</th>
</tr>
<xsl:for-each select="catalog/cd">
<tr>
<td><xsl:value-of select="title" /></td>
<td><xsl:value-of select="artist" /></td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
<html>
<body>
<script type="text/javascript">
// Load XML
var xml = new ActiveXObject("Microsoft.XMLDOM")
xml.async = falsehttp://write.blog.csdn.net/postedit/51356238
xml.load("cdcatalog.xml")
// Load XSL
var xsl = new ActiveXObject("Microsoft.XMLDOM")
xsl.async = false
xsl.load("cdcatalog.xsl")
// Transform
document.write(xml.transformNode(xsl))
</script>
</body>
</html>
根据 DOM,XML 文档中的每个成分都是一个节点。
DOM 是这样规定的:
- 整个文档是一个文档节点
- 每个 XML 标签是一个元素节点
- 包含在 XML 元素中的文本是文本节点
- 每一个 XML 属性是一个属性节点
- 注释属于注释节点
文本总是存储在文本节点中:在 DOM 处理中一个普遍的错误是,认为元素节点包含文本。不过,元素节点的文本是存储在文本节点中的。在这个例子中:<year>2005</year>,元素节点 <year>,拥有一个值为 "2005" 的文本节点。"2005"不是 <year> 元素的值!
2.XML DOM 树:
XML DOM 把 XML DOM 文档视为一棵节点树 (node-tree)。树中的所有节点彼此之间都有关系。可通过这棵树访问所有节点。可以修改或删除它们的内容,也可以创建新的元素。
大多数浏览器都内建了供读取和操作 XML 的 XML 解析器。析器把 XML 读入内存,并把它转换为可被 JavaScript 访问的 XML DOM 对象。微软的 XML 解析器与其他浏览器中的解析器是有差异的。微软的解析器支持对 XML 文件和 XML 字符串(文本)的加载,
而其他浏览器使用单独的解析器。不过,所有的解析器都含有遍历 XML 树、访问、插入及删除节点的函数。
3.1.加载并解析XML文件:(book.xml)
1、解析<strong>XML文档</strong> 成XML DOM对象:
用微软的XML解析器加载XML:(微软的 XML 解析器内建于 Internet Explorer 5 及更高版本中。)
//加载XML文档
<pre name="code" class="javascript"> xmlDoc=new ActiveXObject("Microsoft.XMLDOM");//IE11不支持ActiveXObject。
xmlDoc.async="false";
xmlDoc.load("books.xml");
//加载XML字符串:
xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
xmlDoc.async="false";
xmlDoc.loadXML(txt);
在 Firefox 及其他浏览器中的 XML 解析器
//加载XML文档
xmlDoc=document.implementation.createDocument("","",null);
xmlDoc.async="false";
xmlDoc.load("books.xml");
//加载XML字符串
parser=new DOMParser();
xmlDoc=parser.parseFromString(txt,"text/xml");
示例:
//加载XML文档:
<pre name="code" class="javascript"> try //Internet Explorer
{
xmlDoc = new ActiveXObject("Microsoft.XMLDOM");//由于IE11不支持ActiveXObject,故这种方法在IE11中失效(需要在IE11 internet options中把安全等级降低才可用)
}
catch (e) {
try //Firefox, Mozilla, Opera, etc.
{
xmlDoc = document.implementation.createDocument("", "", null);
}
catch (e) { alert(e.message) }
}
try {
xmlDoc.async = false;
xmlDoc.load("/example/xdom/books.xml");
document.write("xmlDoc is loaded, ready for use");
}
catch (e) { alert(e.message) }
或:改进如下,使用xmlhttp来Get XMl domif (window.XMLHttpRequest){// code for IE7+, Firefox, Chrome, Opera, Safarixmlhttp=new XMLHttpRequest();}else{// code for IE6, IE5xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");}xmlhttp.open("GET","books.xml",false);xmlhttp.send();xmlDoc=xmlhttp.responseXML;
//加载XML字符串txt="<bookstore><book>";txt=txt+"<title>Everyday Italian</title>";txt=txt+"<author>Giada De Laurentiis</author>";txt=txt+"<year>2005</year>";txt=txt+"</book></bookstore>";if (window.DOMParser){parser=new DOMParser();xmlDoc=parser.parseFromString(txt,"text/xml");}else // Internet Explorer{xmlDoc=new ActiveXObject("Microsoft.XMLDOM");//IE11不支持xmlDoc.async=false;xmlDoc.loadXML(txt);}4.XML DOM 属性和方法:XML DOM 属性:一些典型的 DOM 属性: (x 是一个节点对象)•x.nodeName - x 的名称•x.nodeValue - x 的值x.nodeType-x的节点类型•x.parentNode - x 的父节点•x.childNodes - x 的子节点•x.attributes - x 的属性节点XML DOM 方法•x.getElementsByTagName(name) - 获取带有指定标签名称的所有元素•x.appendChild(node) - 向 x 插入子节点•x.removeChild(node) - 从 x 删除子节点
var txt = xmlDoc.getElementsByTagName("title")[0].childNodes[0].nodeValue
<ul><li><em>xmlDoc</em> - 由解析器创建的 XML DOM</li><li><em>getElementsByTagName("title")[0]</em> - 第一个 <title> 元素</li><li><em>childNodes[0]</em> - <title> 元素的第一个子节点 (文本节点) </li><li><em>nodeValue</em> - 节点的值 (文本自身)</li></ul>
5.XML DOM 访问节点:
通过 DOM,您能够访问 XML 文档中的每个节点。
您可以通过三种方法来访问节点:
5.1.通过使用 getElementsByTagName() 方法:
返回 x 元素下的所有 <title> 元素:x.getElementsByTagName("title");
返回 XML 文档中的所有 <title> 元素:xmlDoc.getElementsByTagName("title");
length 属性定义节点列表的长度(即节点的数目)。通过使用 length 属性来循环一个节点列表:
xmlDoc=loadXMLDoc("books.xml");
x=xmlDoc.getElementsByTagName("title");
for (i=0;i<x.length;i++)
{
document.write(x[i].childNodes[0].nodeValue);
document.write("<br />");
}
5.2.通过循环(遍历)节点树
下面的代码循环根节点的子节点,同时也是元素节点:
xmlDoc=loadXMLDoc("books.xml");
x=xmlDoc.documentElement.childNodes;
for (i=0;i<x.length;i++)
{
if (x[i].nodeType==1)
{//Process only element nodes (type 1)
document.write(x[i].nodeName);
document.write("<br />");
}
}
5.3.通过利用节点的关系在节点树中导航
下面的代码通过利用节点的关系在节点树中进行导航:
xmlDoc=loadXMLDoc("books.xml");
x=xmlDoc.getElementsByTagName("book")[0].childNodes;
y=xmlDoc.getElementsByTagName("book")[0].firstChild;
for (i=0;i<x.length;i++)
{
if (y.nodeType==1)
{//Process only element nodes (type 1)
document.write(y.nodeName + "<br />");
}
y=y.nextSibling;
}
6.XML DOM节点信息:
节点属性:nodeName、nodeValue 以及 nodeType。
6.1.nodeName:
•nodeName 是只读的
•元素节点的 nodeName 与标签名相同
•属性节点的 nodeName 是属性的名称
•文本节点的 nodeName 永远是 #text
•文档节点的 nodeName 永远是 #document
6.2.nodeValue:
•元素节点的 nodeValue 是 undefined
•文本节点的 nodeValue 是文本自身
•属性节点的 nodeValue 是属性的值
6.3.nodeType:
nodeType 属性规定节点的类型。
nodeType 是只读的。
最重要的节点类型是:
元素类型 | 节点类型 |
---|---|
元素 | 1 |
属性 | 2 |
文本 | 3 |
注释 | 8 |
文档 | 9 |
7.XML DOM 节点列表:
节点列表由 getElementsByTagName() 方法和 childNodes 属性返回。
xmlDoc=loadXMLDoc("books.xml");
x=xmlDoc.getElementsByTagName("title");
txt=x[0].childNodes[0].nodeValue;
节点列表的 length 属性是列表中节点的数量。
8.XML DOM 节点属性列表:
元素节点的 attributes 属性返回节点的属性列表。
xmlDoc=loadXMLDoc("books.xml");
x=xmlDoc.getElementsByTagName('book')[0].attributes;
x.length 等于属性的数量,可使用 x.getNamedItem() 返回属性节点。
xmlDoc=loadXMLDoc("books.xml");
x=xmlDoc.getElementsByTagName("book")[0].attributes;
document.write(x.getNamedItem("category").nodeValue);
document.write("<br />" + x.length);
9.XML DOM 浏览器差异:
所有现代浏览器都支持 W3C DOM 规范。不过,浏览器之间是有差异的。重要的区别有两点:
•加载 XML 的方式
•处理空白和换行的方式
XML 经常在节点之间含有换行或空白字符。这是在使用简单的编辑器(比如记事本)时经常出现的情况。Firefox,以及其他一些浏览器,会把空的空白或换行作为文本节点来处理,而 Internet Explorer 不会这样。
如需忽略元素节点之间的空文本节点,需要检查节点类型。元素节点的类型是 1:
x=xmlDoc.documentElement.childNodes;
for (i=0;i<x.length;i++)
{
if (x[i].nodeType==1)//检查每个子节点的节点类型。如果节点类型是 "1",则是元素节点
{// only process element nodes
document.write(x[i].nodeName);
document.write("<br />");
}
10.XML DOM 定位节点:
可通过使用节点间的关系对节点进行定位。
在 XML DOM 中,节点的关系被定义为节点的属性:
•parentNode
•childNodes
•firstChild
•lastChild
•nextSibling
•previousSibling
Firefox,以及其他一些浏览器,把空的空白或换行当作文本节点,而 IE 不会这么做。这会在使用下列属性使产生一个问题:firstChild、lastChild、nextSibling、previousSibling。
这会在使用下列属性使产生一个问题:firstChild、lastChild、nextSibling、previousSibling。
function get_nextSibling(n)
{
y=n.nextSibling;
while (y.nodeType!=1)
{
y=y.nextSibling;
}
return y;
}
有了上面的函数,我们就可以使用 get_nextSibling(node) 来代替 node.nextSibling 属性。
11.XML DOM 节点操作:
11.1.获取节点值:
nodeValue 属性用于获取节点的文本值。
getAttribute() 方法返回属性的值。
getAttributeNode() 方法返回属性节点。
xmlDoc=loadXMLDoc("books.xml");
txt=xmlDoc.getElementsByTagName("title")[0].getAttribute("lang");//把 txt 变量设置为第一个 title 元素节点的 "lang" 属性的值
x=xmlDoc.getElementsByTagName("title")[0].getAttributeNode("lang");//获取第一个 <title> 元素节点的 "lang" 属性节点
txt=x.nodeValue;
11.2.改变节点值:
nodeValue 属性用于改变节点值。
setAttribute() 方法用于改变属性的值。
xmlDoc=loadXMLDoc("books.xml");
x=xmlDoc.getElementsByTagName('book');
x[0].setAttribute("category","child");
11.3.删除节点:
removeChild() 方法删除指定节点。 removeAttribute() 方法删除指定属性。
removeAttribute() 方法删除指定属性。
removeAttributeNode(node) 方法通过使用 Node 对象作为参数,来删除属性节点。
11.3.1.
xmlDoc=loadXMLDoc("books.xml");
y=xmlDoc.getElementsByTagName("book")[0];
xmlDoc.documentElement.removeChild(y); //通过使用 removeChild() 方法<strong>从父节点删除元素节点</strong>
x=xmlDoc.getElementsByTagName("book")[0];
x.parentNode.removeChild(x);//通过使用 <strong>parentNode </strong>属性和 removeChild() 方法来<strong>删除此元素节点</strong>
x=xmlDoc.getElementsByTagName("title")[0];//x 设置为第一个 title 元素节点
y=x.childNodes[0];//y 设置为 要删除的文本节点
x.removeChild(y); /<strong>/删除文本节点</strong>
11.3.2
不太常用 removeChild() 从节点删除文本。可以使用 nodeValue 属性代替它:
xmlDoc=loadXMLDoc("books.xml");
x=xmlDoc.getElementsByTagName("title")[0].childNodes[0];
x.nodeValue=""; //使用 nodeValue 属性来清空文本节点的文本
11.3.3.根据名称删除属性节点
removeAttribute(name) 方法用于根据名称删除属性节点。
xmlDoc=loadXMLDoc("books.xml");
x=xmlDoc.getElementsByTagName("book");
x[0].removeAttribute("category"); //从第一个 book 元素节点中删除 "category" 属性
11.3.4.根据对象删除属性节点
removeAttributeNode(node) 方法通过使用 Node 对象作为参数,来删除属性节点。
下面的代码片段删除所有 <book> 元素的所有属性:
xmlDoc=loadXMLDoc("books.xml");
x=xmlDoc.getElementsByTagName("book");
for (i=0;i<x.length;i++)
{
while (x[i].attributes.length>0)//检查每个 book 元素是否拥有属性,如果在某个 book 元素中存在属性,则删除该属性
{
attnode=x[i].attributes[0];
old_att=x[i].removeAttributeNode(attnode);
}
}
11.4.替换节点:
replaceChild() 方法替换指定节点。
replaceData() 方法用于替换文本节点中的数据。
nodeValue 属性替换文本节点中的文本。(用 nodeValue 属性来替换文本节点中数据会更加容易)
11.4.1.replaceChild()
xmlDoc=loadXMLDoc("books.xml");
x=xmlDoc.documentElement;
//创建一个 book 元素、一个 title 元素,以及一个 text 节点
newNode=xmlDoc.createElement("book");
newTitle=xmlDoc.createElement("title");
newText=xmlDoc.createTextNode("Hello World");
//向 title 节点添加文本节点
newTitle.appendChild(newText);
//向 book 节点添加 title 节点
newNode.appendChild(newTitle);
y=xmlDoc.getElementsByTagName("book")[0];
//用这个新节点替换第一个 book 节点
x.replaceChild(newNode,y);
11.4.2.replaceData()
replaceData() 方法有三个参数:
•offset - 在何处开始替换字符。Offset 值以 0 开始。
•length - 要替换多少字符
•string - 要插入的字符串
xmlDoc=loadXMLDoc("books.xml");
x=xmlDoc.getElementsByTagName("title")[0].childNodes[0];
x.replaceData(0,8,"hello");//使用 replaceDat 方法把文本节点的前 8 个字符替换为 "hello"
11.4.3.nodeValue 属性
xmlDoc=loadXMLDoc("books.xml");
x=xmlDoc.getElementsByTagName("title")[0].childNodes[0];
x.nodeValue="Hello World";//使用 nodeValue 属性来更改这个文本节点的文本
11.5.创建节点
11.5.1. 创建新的元素节点:createElement()
xmlDoc=loadXMLDoc("books.xml");
newel=xmlDoc.createElement("edition");//创建一个新的元素节点 <edition>
x=xmlDoc.getElementsByTagName("book")[0];
x.appendChild(newel);
11.5.2.创建新的属性节点:createAttribute()
xmlDoc=loadXMLDoc("books.xml");
newatt=xmlDoc.createAttribute("edition");//创建一个新的属性节点 "edition"
newatt.nodeValue="first";
x=xmlDoc.getElementsByTagName("title");
x[0].setAttributeNode(newatt);
通过使用 setAttribute() 来创建属性:由于 setAttribute() 可以在属性不存在的情况下创建新的属性,我们可以使用这个方法来创建新属性
xmlDoc=loadXMLDoc("books.xml");
x=xmlDoc.getElementsByTagName('book');
x[0].setAttribute("edition","first");
11.5.3.创建文本节点:createTextNode()
newel=xmlDoc.createElement("edition");
newtext=xmlDoc.createTextNode("first");//创建一个新的文本节点,其文本是 "first"
newel.appendChild(newtext);
x=xmlDoc.getElementsByTagName("book")[0];
x.appendChild(newel);
11.5.4.创建一个CDATA Section节点:createCDATASection()
xmlDoc=loadXMLDoc("books.xml");
newCDATA=xmlDoc.createCDATASection("Special Offer & Book Sale");//创建一个新的注释节点
x=xmlDoc.getElementsByTagName("book")[0];
x.appendChild(newCDATA);
11.6.填加节点:
11.6.1.填加节点:appendChild()
appendChild() 方法向已存在的节点添加子节点。新节点会添加(追加)到任何已存在的子节点之后。
xmlDoc=loadXMLDoc("books.xml");
newel=xmlDoc.createElement("edition");
x=xmlDoc.getElementsByTagName("book")[0];
x.appendChild(newel);//把这个节点追加到第一个 <book> 元素
11.6.2.插入节点:insertBefore()
insertBefore() 方法用于在指定的子节点之前插入节点。在被添加的节点的位置很重要时,此方法很有用。
xmlDoc=loadXMLDoc("books.xml");
newNode=xmlDoc.createElement("book");
x=xmlDoc.documentElement;
y=xmlDoc.getElementsByTagName("book")[3];
x.insertBefore(newNode,y);//把这个节点插到最后一个 <book> 元素节点之前
如果 insertBefore() 的第二个参数是 null,新节点将添加到最后一个已有的子节点之后:
x.insertBefore(newNode,null) 和
x.appendChild(newNode) 都可以向 x 追加一个新的子节点。
11.6.3.填加属性:
addAtribute() 这个方法是不存在的,如果属性不存在,则 setAttribute() 可创建一个新的属性:
xmlDoc=loadXMLDoc("books.xml");
x=xmlDoc.getElementsByTagName('book');
x[0].setAttribute("edition","first");
11.6.4.向文本节点填加文本:insertData()
insertData() 方法将数据插入已有的文本节点中。
insertData() 方法有两个参数:
•offset - 在何处开始插入字符(以 0 开始)
•string - 要插入的字符串
xmlDoc=loadXMLDoc("books.xml");
x=xmlDoc.getElementsByTagName("title")[0].childNodes[0];
x.insertData(0,"Hello ");//把 "Easy" 添加到已加载的 XML 的第一个 <title> 元素的文本节点:
11.7.克隆节点:cloneNode()
cloneNode() 方法创建指定节点的副本。cloneNode() 方法有一个参数(true 或 false)。该参数指示被复制的节点是否包括原节点的所有属性和子节点。
xmlDoc=loadXMLDoc("books.xml");
oldNode=xmlDoc.getElementsByTagName('book')[0];
newNode=oldNode.cloneNode(true);
xmlDoc.documentElement.appendChild(newNode);
//Output all titles
y=xmlDoc.getElementsByTagName("title");
for (i=0;i<y.length;i++)
{
document.write(y[i].childNodes[0].nodeValue);
document.write("<br />");
}
11.8.XMLHttpRequest对象:
XMLHttpRequest 对象提供了在网页加载后与服务器进行通信的方法。所有现代的浏览器都支持 XMLHttpRequest 对象。
创建 XMLHttpRequest 对象:
在所有现代浏览器中(包括 IE 7):xmlhttp=new XMLHttpRequest()
Internet Explorer 5 和 6 中:xmlhttp=new ActiveXObject("Microsoft.XMLHTTP")
<script type="text/javascript">
var xmlhttp;
function loadXMLDoc(url)
{
xmlhttp=null;
if (window.XMLHttpRequest)
{// code for all new browsers
xmlhttp=new XMLHttpRequest();
}
else if (window.ActiveXObject)
{// code for IE5 and IE6
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
if (xmlhttp!=null)
{
xmlhttp.onreadystatechange=state_Change;
xmlhttp.open("GET",url,true);
xmlhttp.send(null);
}
else
{
alert("Your browser does not support XMLHTTP.");
}
}
function state_Change()
{
if (xmlhttp.readyState==4)
{// 4 = "loaded"
if (xmlhttp.status==200)
{// 200 = OK
// ...our code here...
}
else
{
alert("Problem retrieving XML data");
}
}
}
</script>
onreadystatechange 是一个事件句柄。它的值 (state_Change) 是一个函数的名称,当 XMLHttpRequest 对象的状态发生改变时,会触发此函数。状态从 0 (uninitialized) 到 4 (complete) 进行变化。仅在状态为 4 时,我们才执行代码。
open() 的第三个参数中使用了 "true"。该参数规定请求是否异步处理。True 表示脚本会在 send() 方法之后继续执行,而不等待来自服务器的响应。onreadystatechange 事件使代码复杂化了。但是这是在没有得到服务器响应的情况下,防止代码停止的最安全的方法。
通过把该参数设置为 "false",可以省去额外的 onreadystatechange 代码。如果在请求失败时是否执行其余的代码无关紧要,那么可以使用这个参数。
xml序列化为实体类:http://blog.okbase.net/haobao/archive/62.html http://www.cnblogs.com/KeithWang/archive/2012/02/22/2363443.html http://www.cnblogs.com/yukaizhao/archive/2011/07/22/xml-serialization.html http://www.cnblogs.com/fish-li/archive/2013/05/05/3061816.html#_label15