如何使用xPath从命名空间xml中检索特定元素
问题描述:
我有一个关于从命名空间xml中检索节点的问题。只要我在查询中指定xml的单个元素,我就可以检索所有匹配的元素,并且可以遍历他们的子元素。我尝试通过指定更详细的查询来检索单个唯一元素时,出现问题。如何使用xPath从命名空间xml中检索特定元素
XML文件,我使用测试
<?xml version="1.0" encoding="utf-8"?>
<<MTConnectStreams xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:mtconnect.org:MTConnectStreams:1.2 http://mtconnect.org/schemas/MTConnectStreams_1.2.xsd" xmlns="urn:mtconnect.org:MTConnectStreams:1.2">
<Streams>
<Samples>
<Position dataItemId="xs4" timestamp="2012-11-29T12:30:19Z" sequence="1718269" name="x_pos_cmd" subType="COMMANDED" units="MILLIMETER">1</Position>
<Position dataItemId="xs5" timestamp="2012-11-29T12:30:19Z" sequence="1718270" name="x_pos_act" subType="ACTUAL" units="MILLIMETER">2</Position>
<Position dataItemId="xs4" timestamp="2012-11-29T12:30:19Z" sequence="1718269" name="y_pos_cmd" subType="COMMANDED" units="MILLIMETER">3</Position>
<Position dataItemId="xs4" timestamp="2012-11-29T12:30:19Z" sequence="1718269" name="y_pos_act" subType="COMMANDED" units="MILLIMETER">4</Position>
<Position dataItemId="xs4" timestamp="2012-11-29T12:30:19Z" sequence="1718269" name="z_pos_cmd" subType="COMMANDED" units="MILLIMETER">5</Position>
</Samples>
<Condition>
<Unavailable dataItemId="xc1" type="POSITION" timestamp="2012-11-27T23:19:40Z" sequence="7" name="x_cond_pos">UNAVAILABLE</Unavailable>
<Unavailable dataItemId="xc2" type="LOAD" timestamp="2012-11-27T23:19:40Z" sequence="8" name="x_cond_load">UNAVAILABLE</Unavailable>
</Condition>
</Streams>
</MTConnectStreams>
考虑下面的代码:
Dim xIt As XPathNodeIterator
Dim xDoc As XmlDocument = New XmlDocument
xDoc.Load("c:\Download\Test.xml")
Dim xNav As XPathNavigator = xDoc.CreateNavigator
Dim nsMgr = New XmlNamespaceManager(xNav.NameTable)
nsMgr.AddNamespace("ns", "urn:mtconnect.org:MTConnectStreams:1.2")
sQuery = "//ns:Samples"
xIt = xNav.Select(sQuery, nsMgr)
MsgBox(xIt.Count.ToString)
When sQuery = "//ns:Samples" (1 result)
When sQuery = "//ns:Position" (5 results)
When sQuery = "//ns:Samples/Position (0 results why?)
When sQuery = "//ns:Samples/Position[@name='x_pos_act'] (0 results)
When sQuery = "//ns:Position[@name='x_pos_act']" (0 results)
When sQuery = "//ns:Position/[@name='x_pos_act']" (0 results)
等等等等,只要查询比单个节点名称我没有得到任何结果的更多。我无法弄清楚如何指定更详细的查询。
答
它应该使用//ns:Samples/ns:Position
AFAIK XPath中,你必须指定每个分部命名空间前缀。这也适用于属性!
所以尝试:
When sQuery = "//ns:Samples"
When sQuery = "//ns:Position"
When sQuery = "//ns:Samples/ns:Position
When sQuery = "//ns:Samples/ns:Position[@ns:name='x_pos_act']
When sQuery = "//ns:Position[@ns:name='x_pos_act']"
When sQuery = "//ns:Position/[@ns:name='x_pos_act']"
如果你不想考虑命名空间,你也可以使用@*[local-name()='Samples']
语法。这将忽略所有的名称空间,只检查节点名称本身。
谢谢。就是这样。奇怪的是不得不反复指定命名空间。看起来像你应该能够做一些事情,比如在你的导航器或迭代器对象的属性中设置你想要处理的命名空间,它会假设你是指你的命名空间。无论如何,再次感谢您的帮助。 – Robb 2013-03-14 17:26:06