使用 XPath 导航选择节点
本文内容
XML 文档对象模型 (DOM) 包含的方法使您可以使用 XML 路径语言 (XPath) 浏览功能查询 DOM 中的信息。 可以使用 XPath 查找单个特定节点,或查找与某个条件匹配的所有节点。
XPath 选择方法
DOM 类提供两种 XPath 选择方法:SelectSingleNode 方法和 SelectNodes 方法。 SelectSingleNode 方法返回符合选择条件的第一个节点。 SelectNodes 方法返回包含匹配节点的 XmlNodeList。
下面的示例使用 SelectSingleNode 方法来选择其作者姓氏符合指定条件的第一个 book
节点。 bookstore.xml 文件(在本主题末尾提供)用作输入文件。
// Load the document and set the root element.
XmlDocument doc = new XmlDocument();
doc.Load("bookstore.xml");
XmlNode root = doc.DocumentElement;
// Add the namespace.
XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
nsmgr.AddNamespace("bk", "urn:newbooks-schema");
// Select and display the first node in which the author's
// last name is Kingsolver.
XmlNode node = root.SelectSingleNode(
"descendant::bk:book[bk:author/bk:last-name='Kingsolver']", nsmgr);
Console.WriteLine(node.InnerXml);
下一个示例使用 SelectNodes 方法来选择其价格大于指定金额的所有书节点。 然后,以编程方式将选定列表中的每本书的价格减去 10%。 最后,将更新的文件写入控制台。 bookstore.xml 文件(在本主题末尾提供)用作输入文件。
// Load the document and set the root element.
XmlDocument doc = new XmlDocument();
doc.Load("bookstore.xml");
XmlNode root = doc.DocumentElement;
// Add the namespace.
XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
nsmgr.AddNamespace("bk", "urn:newbooks-schema");
// Select all nodes where the book price is greater than 10.00.
XmlNodeList nodeList = root.SelectNodes(
"descendant::bk:book[bk:price>10.00]", nsmgr);
foreach (XmlNode book in nodeList)
{
// Discount prices by 10%.
double price;
price = Math.Round(Convert.ToSingle(
book.LastChild.InnerText) * 0.9, 2);
book.LastChild.InnerText = price.ToString();
}
// Display the updated document.
doc.Save(Console.Out);
上面的示例从文档元素开始执行 XPath 查询。 设置 XPath 查询的起始点即设置了上下文节点,该节点是 XPath 查询的起始点。 如果不希望在文档元素处开始,而是希望从文档元素的第一个子级开始,可以编写 Select 语句的代码,如下所示:
this doc.DocumentElement.FirstChild.SelectNodes(. . .);
所有 XmlNodeList 对象都与基础文档同步。 因此,如果循环访问节点列表并修改某个节点的值,则该节点在包含它的文档中也被更新。 请注意,在上一个示例中,在选定的 XmlNodeList 中修改节点时,也会修改基础文档。
备注
修改基础文档时,最好重新运行此 Select 语句。 如果修改的节点可能导致该节点被添加到节点列表(当先前没有添加它时),或者现在会导致它从节点列表中被移除,则无法保证节点列表现在是精确的。
XPath 表达式中的命名空间
XPath 表达式可以包含命名空间。 使用 XmlNamespaceManager 支持命名空间解析。 如果 XPath 表达式包含前缀,前缀和命名空间 URI 对必须添加到 XmlNamespaceManager,并且 XmlNamespaceManager 传递给 SelectNodes(String, XmlNamespaceManager) 或 SelectSingleNode(String, XmlNamespaceManager) 方法。 请注意,上面的代码示例使用 XmlNamespaceManager 来解析 bookstore.xml 文档的命名空间。
备注
如果 XPath 表达式不包含前缀,则假定命名空间统一资源标识符 (URI) 是空的命名空间。 如果 XML 包含默认命名空间,仍必须将前缀和命名空间 URI 添加到 XmlNamespaceManager;否则,不会选择任何节点。
输入文件
下面的 bookstore.xml 文件在本主题的示例中用作输入文件。
<?xml version='1.0'?>
<bookstore xmlns="urn:newbooks-schema">
<book genre="novel" style="hardcover">
<title>The Handmaid's Tale</title>
<author>
<first-name>Margaret</first-name>
<last-name>Atwood</last-name>
</author>
<price>19.95</price>
</book>
<book genre="novel" style="other">
<title>The Poisonwood Bible</title>
<author>
<first-name>Barbara</first-name>
<last-name>Kingsolver</last-name>
</author>
<price>11.99</price>
</book>
<book genre="novel" style="paperback">
<title>The Bean Trees</title>
<author>
<first-name>Barbara</first-name>
<last-name>Kingsolver</last-name>
</author>
<price>5.99</price>
</book>
</bookstore>
请参阅
XPath 查询和命名空间
本文内容
XPath 查询支持 XML 文档中的命名空间,可以使用命名空间前缀来限定元素和属性的名称。 使用命名空间前缀来限定元素和属性的名称可以限制 XPath 查询只返回属于特定命名空间的节点。
例如,如果前缀 books
映射到命名空间 http://www.contoso.com/books
,以下 XPath 查询 /books:books/books:book
将只选择命名空间 book
中的 http://www.contoso.com/books
元素。
XmlNamespaceManager
要在 XPath 查询中使用命名空间,构造一个从 IXmlNamespaceResolver 接口派生的对象(例如 XmlNamespaceManager 类),包含要加入 XPath 查询的命名空间 URI 和前缀。
XmlNamespaceManager 对象可以通过下列任意方式在查询中使用。
-
使用 XmlNamespaceManager 对象的 XPathExpression 方法将 SetContext 对象与现有的 XPathExpression 对象关联。 还可以使用静态 XPathExpression 方法编译新的 Compile 对象,该方法使用表示 XPath 表达式的字符串和 XmlNamespaceManager 对象作为参数,并返回一个新的 XPathExpression 对象。
-
XmlNamespaceManager 对象本身与表示 XPath 表达式的字符串一起作为参数传递给接受方的 XPathNavigator 类方法。
以下是 XPathNavigator 类中接受从 IXmlNamespaceResolver 接口派生的对象作为参数的方法。
默认命名空间
在下面的 XML 文档中,具有空前缀的默认命名空间用于声明 http://www.contoso.com/books
命名空间。
<books xmlns="http://www.contoso.com/books">
<book>
<title>Title</title>
<author>Author Name</author>
<price>5.50</price>
</book>
</books>
XPath 将空前缀作为 null
命名空间对待。 也就是说,XPath 查询中只能使用映射到命名空间上的前缀。 这意味着如果要针对 XML 文档中的某个命名空间进行查询,即使是默认的命名空间,也需要为其定义前缀。
例如,在没有为上面的 XML 文档定义前缀的情况下,XPath 查询 /books/book
不会返回任何结果。
必须绑定前缀,这样,如果查询的文档中有些节点在某个命名空间,有些节点在默认命名空间,可以避免混淆情况。
以下代码为默认命名空间定义前缀,并选择 book
命名空间中的所有 http://www.contoso.com/books
元素。
XPathDocument document = new XPathDocument("books.xml");
XPathNavigator navigator = document.CreateNavigator();
XPathExpression query = navigator.Compile("/books:books/books:book");
XmlNamespaceManager manager = new XmlNamespaceManager(navigator.NameTable);
manager.AddNamespace("books", "http://www.contoso.com/books");
query.SetContext(manager);
XPathNodeIterator nodes = navigator.Select(query);
请参阅
XPath 命名空间浏览
本文内容
要对 XML 文档使用 XPath 查询,必须正确定位 XML 命名空间以及命名空间中包含的元素。 命名空间可防止在多个上下文中使用名称时可能产生的混淆情况;例如,名称 ID
可能引用与 XML 文档的不同元素相关联的多个标识符。 命名空间语法指定了 URI、名称和前缀,可区分 XML 文档的各个元素。
本主题中的示例演示了通过 XPathNavigator 在浏览 XML 文档时使用前缀。 有关命名空间和语法的详细信息,请参阅 XML 文件:了解 XML 命名空间。
命名空间声明
命名空间声明使得在使用 XPathNavigator 的实例时,很容易区分和定位 XML 文档的各个元素。 命名空间前缀提供了一种简化的语法,用来定位命名空间。
前缀由以下形式定义:<e:Envelope xmlns:e=http://schemas.xmlsoap.org/soap/envelope/>.
在此语法中,前缀“e
”是命名空间的正式 URI 的缩写。 使用此语法可以将 Body
元素标识为 Envelope
命名空间的成员:e:Body
。
在下一节的浏览示例中,下面的 XML 文档将用作 response.xml
。
<?xml version="1.0" encoding="utf-8" ?>
<e:Envelope xmlns:e="http://schemas.xmlsoap.org/soap/envelope/">
<e:Body>
<s:Search xmlns:s="http://schemas.microsoft.com/v1/Search">
<r:request xmlns:r="http://schemas.microsoft.com/v1/Search/metadata"
xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
</r:request>
</s:Search>
</e:Body>
</e:Envelope>
通过命名空间前缀进行浏览
本节中的代码使用 XPathNavigator 和 XmlNamespaceManager 对象,从前一节的 XML 文档中选择 Search
元素。 查询 xpath
对路径中的每个元素都包含了命名空间前缀。 指定包含每个元素的命名空间的精确标识,可确保通过 Search
方法正确浏览至 SelectSingleNode 元素。
using (XmlReader reader = XmlReader.Create("response.xml"))
{
XPathDocument doc = new XPathDocument(reader);
XPathNavigator nav = doc.CreateNavigator();
XmlNamespaceManager nsmgr = new XmlNamespaceManager(nav.NameTable);
nsmgr.AddNamespace("e", @"http://schemas.xmlsoap.org/soap/envelope/");
nsmgr.AddNamespace("s", @"http://schemas.microsoft.com/v1/Search");
nsmgr.AddNamespace("r", @"http://schemas.microsoft.com/v1/Search/metadata");
nsmgr.AddNamespace("i", @"http://www.w3.org/2001/XMLSchema-instance");
string xpath = "/e:Envelope/e:Body/s:Search";
XPathNavigator element = nav.SelectSingleNode(xpath, nsmgr);
Console.WriteLine("Element Prefix:" + element.Prefix +
" Local name:" + element.LocalName);
Console.WriteLine("Namespace URI: " + element.NamespaceURI);
}
完全限定的命名空间和名称的精确度不仅仅是一种方便。 对前面的示例中的文档定义和代码进行一项小实验,可以验证如果不使用完全限定的元素名称进行浏览,就会引发异常。 例如,元素定义为 <Search xmlns="http://schemas.microsoft.com/v1/Search">
,而查询字符串 xpath = "/s:Envelope/s:Body/Search";
没有对 Search
元素使用命名空间前缀,则此查询将返回 null
,而不是 Search
元素。
请参阅
Microsoft XML 3.0 - XML Reference |
setProperty Method
Sets the SelectionLanguage, ServerHTTPRequest, or SelectionNamespaces internal properties (flags).
Important For servers running on an intranet, the ServerHTTPRequest property requires you to run a proxycfg.exe utility to configure WinHTTP's proxy settings. They cannot be configured through the Microsoft® Windows® Control Panel. To download the proxy configuration utility, go to the XML Development Center's WinHTTP Proxy Configuration Utility page. For instructions about running the proxycfg.exe utility, see Using the WinHTTP Proxy Configuration Utility. After you have run the proxycfg.exe tool and updated the registry, the previous registry settings cannot be restored.
Remarks
The following table shows the properties that you can set using this method. Existing properties from DOMDocument are not accessible through this method. White space is not stripped or normalized in property names or values.
Name | Value |
---|---|
SelectionLanguage internal property (flag) | "XPath" or "XSLPattern"
The SelectionLanguage property defaults to "XSLPattern". This property indicates the type of query the user plans to pass into selectNodes or selectSingleNode. "XSLPattern" is the default for backward compatibility. This flag applies to all nodes whose ownerDocument property points to this document object. Therefore, if a given node is moved to a different document, its selectNode behavior may change depending on the SelectionLanguage setting in the new document. The following Jscript example on the client shows how to set the SelectionLanguage to XPath for the xmldoc object. var xmldoc = new ActiveXObject("Msxml2.DOMDocument"); var selection; xmldoc.loadXML ("<Customer><Name>Microsoft</Name></Customer>"); xmldoc.setProperty("SelectionLanguage", "XPath"); selection = xmldoc.selectNodes("Customer/Name"); alert(selection.expr + " -- " + selection.item(0).xml); |
ServerHTTPRequest internal property (flag) | True/False value indicating if the "server-safe" ServerXMLHTTP component should be used to load a document to a server. This only supports synchronous loading; thus, the async property must be set to False when ServerXMLHTTP is set to True.
For example: <%@language=JScript%> <% var xmlDoc; xmlDoc = Server.CreateObject("Msxml2.DomDocument"); xmlDoc.async = false; xmlDoc.setProperty("ServerHTTPRequest", true); xmlDoc.load(http://myserver.com); %> |
SelectionNamespaces internal property (flag) | A space delimited set of Namespace names.
For example: oDomDocument.setProperty("SelectionNamespaces", "xmlns:example1='http://myserver.com' xmlns:example2='http://yourserver.com'"); With the SelectionNamespaces internal property (flag), the selectSingleNode method and selectNodes method can now use qualified names. |
Script Syntax
objXMLDOMDocument2.setProperty(name, value);
Parameters
- name
- The name of the property to be set. For a list of properties that can be set using this method, see Remarks.
- value
- The value of the specified property. For a list of property values that can be set using this method, see Remarks.
Example
var xmlDoc = new ActiveXObject("Msxml2.DOMDocument"); var selection; xmlDoc.loadXML("<Customer><Name>Microsoft</Name></Customer>"); xmlDoc.setProperty("SelectionLanguage", "XPath"); selection = xmlDoc.selectNodes("Customer/Name"); alert(selection.expr + " -- " + selection.item(0).xml);
The preceding message box displays "Customer/Name -- <Name>Microsoft</Name>".
selection.expr = "/Customer"; alert(selection.expr + " -- " + selection.item(0).xml);
The preceding message box displays "/Customer –-<Customer><Name>Microsoft</Name></Customer>".
Visual Basic Syntax
objXMLDOMDocument2.setProperty(name, value)
Parameters
- name
- The name of the property to be set. For a list of properties that can be set using this method, see Remarks.
- value
- The value of the specified property. For a list of property values that can be set using this method, see Remarks.
Example
Dim xmldoc As New Msxml2.DOMDocument Dim selection As Msxml2.IXMLDOMSelection xmldoc.loadXML ("<Customer><Name>Microsoft</Name></Customer>") xmldoc.setProperty "SelectionLanguage", "XPath" Set selection = xmldoc.selectNodes("Customer/Name") MsgBox selection.expr + " -- " + selection.Item(0).xml
The preceding message box displays "Customer/Name -- <Name>Microsoft</Name>".
selection.expr = "/Customer" MsgBox selection.expr + " -- " + selection.Item(0).xml
The preceding message box displays "/Customer –-<Customer><Name>Microsoft</Name></Customer>".
C/C++ Syntax
HRESULT setProperty (BSTR name, VARIANT value);
Parameters
- name [in]
- The name of the property to be set. For a list of properties that can be set using this method, see Remarks.
- value [in]
- The value of the specified property. For a list of property values that can be set using this method, see Remarks.
C/C++ Return Values
- S_OK
- Value returned if successful.
- E_FAIL
- Value returned if name or value is invalid.
See Also
南来地,北往的,上班的,下岗的,走过路过不要错过!
======================个性签名=====================
之前认为Apple 的iOS 设计的要比 Android 稳定,我错了吗?
下载的许多客户端程序/游戏程序,经常会Crash,是程序写的不好(内存泄漏?刚启动也会吗?)还是iOS本身的不稳定!!!
如果在Android手机中可以简单联接到ddms,就可以查看系统log,很容易看到程序为什么出错,在iPhone中如何得知呢?试试Organizer吧,分析一下Device logs,也许有用.