我正在尝试识别树中通往特定节点的所有节点。
我试图通过MSSQL XML(2005)或ASP classic中的Microsoft.XMLDOM来实现这一目标。
我知道XPATH的逻辑,但SQL Server不支持ancestor-or-self
轴,而XMLDOM似乎会阻塞::
表示法。
我在XPATH测试人员中测试它时的xpath是
//static[@id=6]/ancestor-or-self::static
我的XML(在sql server中递归生成)看起来像
<root>
<static id="1" title="some title 1" />
<static id="2" title="some title 2">
<children>
<static id="3" title="some title 3" />
<static id="4" title="some title 4">
<children>
<static id="5" title="some title 5" />
<static id="6" title="some title 6" />
</children>
</static>
</children>
</static>
<static id="7" title="some title 7" />
</root>
XPATH应该以任何顺序选择id(2,4,6)的节点,所以我可以为所有节点添加一个属性..
这是一个菜单系统,我只知道所选择的叶子,并且需要将所有节点标记为hilited ...
如果克服XMLDOM窒息,我将不胜感激
(正在运行xml.documentElement.selectNodes("//static[@id=6]/ancestor-or-self::static")
会产生以下错误:Expected token 'eof' found ':'. //static[@id=6]/ancestor-or-self-->:<--:static
)
或寻找替代解决方案。也许在任何深度找到包含特定节点(id = 6)的所有节点。
答案 0 :(得分:4)
这是一种“整理松散的目的”的答案。
首先,您的主要问题是“Microsoft.XMLDOM”通常会加载3.0版实现(MSXML3.dll)。 MSXML3支持完整的XPATH 1.0语言,但默认情况下不支持。以下应该足以修复: -
dom.SetProperty "SelectionLanguage", "XPath"
Marvin的回答在使用MSXML4时包含了这一行,但由于XPath是4及以上版本的默认选择语言,因此并不是必需的。
但我建议在上面使用应该这个词。我经常遇到被第三方应用程序攻陷的服务器,第三方应用程序也包含MSXML2的分发但是安装不正确。它们导致“Microsoft.XMLDOM”和非特定于版本的“MSXML2.DOMDocument”返回MSXML2.dll实现而不是MSXML3实现。
因此我通常建议使用最好的ProgID是“MSXML2.DOMDocument.3.0”,因为你确切知道你得到了什么。此外,MSXML3.dll保证安装在所有当前支持的Windows操作系统上。当使用较旧的progID调用DOM Document时,MSXML3仍然与MSXML2实现中的错误兼容。使用特定于版本的ProgID会使MSXML3更严格地符合XML标准。
答案 1 :(得分:1)
在W2K3上运行,使用IIS6我测试了MSXML2.XMLDomDocument.4.0版本。
Dim XMLDom ''# As MSXML2.DOMDocument40
Set XMLDom = CreateObject("MSXML2.DOMDocument.4.0")
Call XMLDom.setProperty("SelectionLanguage", "XPath")
Call XMLDom.loadXML( {document as described above - mistakes in original xml doc)
)
Dim originalQuery ''# As String
originalQuery = "//static[@id=6]/ancestor-or-self::static"
Dim replacementQuery ''# As String
replacementQuery = "//static[descendant::static[@id=6] or @id=6]"
Dim XmlElemList ''# As MSXML2.IXMLDOMNodeList
Set XmlElemList = XMLDom.documentElement.selectNodes(originalQuery)
Dim XmlElemList2 ''# As MSXML2.IXMLDOMNodeList
Set XmlElemList2 = XMLDom.documentElement.selectNodes(replacementQuery)
Dim XmlElem ''# As MSXML2.IXMLDOMElement
Call Response.Write("Using original query : '" & originalQuery & "' (" & XmlElemList.Length & ")<br>")
For Each XmlElem In XmlElemList
Call Response.Write("XmlEntry : " & XmlElem.getAttribute("id") & "<br>")
Call Response.Write("****<br>")
Next
Call Response.Write("Using replacement query : '" & replacementQuery & "' (" & XmlElemList2.Length & ")<br>")
For Each XmlElem In XmlElemList2
Call Response.Write("XmlEntry : " & XmlElem.getAttribute("id") & "<br>")
Call Response.Write("****<br>")
Next