如何使用vbscript删除XML文件中的特定节点
我遇到了无法选择需要删除的特定XML节点的问题。我已经尝试通过使用适用于某些XML文件的XPath来选择节点,但我无法找到更复杂文件中节点的正确XPath。如何使用vbscript删除XML文件中的特定节点
有没有人知道一个免费的工具,它可以加载一个XML文件,以便用户可以选择一个特定的节点并接收准确的XPath,而无需在路径中枚举?
/root/anything[2]
< - 不幸的是我不能使用这样的陈述,因为元素的数量可能会改变。我需要一个基于属性的表达式。
如果没有用于此操作的免费软件工具,是否有人知道如何选择所需节点的另一种方式?
XML示例:
根节点: SmsFormData
属性:的xmlns:XSI = “http://www.w3.org/2001/XMLSchema-instance” 的xmlns: xsd =“http://www.w3.org/2001/XMLSchema”FormatVersion =“1.0”xmlns =“http://schemas.microsoft.com/SystemsManagementServer/2005/03/ConsoleFramework”
子节点:表格
个属性:编号= “一些GUID” 的CustomData = “一些数据” FormType = “某种类型的” ForceRefresh = “假”
儿童/子节点:页数
儿童/儿童/子节点:页
属性: VENDORID = “VENDORNAME” ID = “一些GUID” 大会= “dll文件名” 命名空间= “一些命名空间” 类型= “某种” 的helpID = “”>
我的XPath表达式选择此特定网页现在是:
XPATH =/SmsFormData/Form/Pages/Page[@Id="some Guid"]
要做到我用下面的VBScript代码的选择:
Set objDOM = CreateObject("Msxml2.DOMDocument.4.0")
objDOM.async = false
objDOM.load(file)
set objNode = objDOM.selectSingleNode(xPath)
问题现在是objNode
对象是空的。该节点未被选中,但为什么?
这是一个默认的命名空间的问题。尝试包括您在XML加载后,下面的代码:
objDom.SetProperty "SelectionNamespaces", "xmlns:cf=""http://schemas.microsoft.com/SystemsManagementServer/2005/03/ConsoleFramework"""
然后你在你的XPath如使用此cf
前缀:
objDom.SelectSingleNode("/cf:SmsFormData/cf:Form/cf:Pages/cf:Page[@Id='Some Guid']")
虽然这可能看起来有点古怪,它是故意行为。请参阅http://support.microsoft.com/kb/288147了解更多信息,而且您可能会发现http://msdn.microsoft.com/en-us/library/ms950779.aspx也很有用。
鉴于以下XML:
<root>
<anything foo="bar">value1</anything>
<anything foo="qux">value2</anything>
</root>
...你可以使用获得XPath表达式第二个事情节点的值:
/root/anything[@foo="qux"]
(所以,代替编号的指数,你使用@ property =“value”作为选择器)。
至于这样一个自动生成查询的工具,恰当地命名为Visual XPath应该做的伎俩,它是免费的(它甚至带有C#源代码)。
在海报的后续操作之后编辑:这种XPath选择形式对于“简单案例”也适用于最复杂的文档。当然,你必须确保你的XPath表达式是正确的,尽管Visual XPath确实会使用数字索引,但它至少会给你表达式的其余部分,并且你可以很容易地将@ property =“value”选择号码并测试结果。
给定上述示例XML,这个VBscript的:
objDOM.selectSingleNode("/root/anything[@foo=""qux""]/text()").nodeValue
...返回字符串“值2”:根据您的需求,您可能需要再次调整的东西一点点(像可视化工具XPath,或任何好的XPath reference将帮助你)。
感谢您的快速回复!这无疑作品在简单的情况,但这并不在我的具体情况:(
因此,因此让详谈工作:
根节点: SmsFormData
属性:的xmlns:XSI =“http://www.w3.org/2001/XMLSchema-instance”xmlns:xsd =“http://www.w3.org/2001/XMLSchema”FormatVersion =“1.0”xmlns =“http:// schemas .microsoft.com/SystemsManagementServer/2005/03/ConsoleFramework“
子节点:表格
属性:编号= “一些GUID” 的CustomData = “一些数据” FormType = “某种类型的” ForceRefresh = “假”
儿童/子节点: 页
儿童/儿童/子节点:页
属性: VENDORID = “VENDORNAME” ID = “一些GUID” 作为sembly = “DLL文件名” 命名空间= “一些命名空间” 类型= “某种” 的helpID = “”>
我的XPath表达式选择此特定网页现在会是:
XPATH =“/ SmsFormData /表格/页/页[@编号=“部分的Guid”]”
要做到我用下面的VBScript代码的选择:
Set objDOM = CreateObject("Msxml2.DOMDocument.4.0")
objDOM.async = false
objDOM.load(file)
set objNode = objDOM.selectSingleNode(xPath)
的问题是现在的objNode对象为空。该节点未被选中,但为什么?
哦,顺便说一句:感谢Visual XPath提示!我一直在使用它尝试,但不幸的是它的枚举方式:/
您应该真的编辑您的问题以包含这些详细信息 – AnthonyWJones 2008-10-06 11:10:12
你需要使用
objDOM.SetProperty“SelectionLanguage”设置选择语言的XPath“的XPath”
一旦设置这个属性就可以使用完整的XPath来访问任何元素,你想
如果您有Firefox浏览器,你可以简单地安装DOM查看器(只适用于Firefox 3.0需要),以及XPather扩展。然后,您可以在DOM Inspector窗口中遍历所需节点,并且相应的XPath将显示在同一窗口中的XPather工具栏中。
DOM查看器:https://addons.mozilla.org/en-US/firefox/addon/6622
XPather:https://addons.mozilla.org/en-US/firefox/addon/1192?id=1192
的XPather似乎使用属性(而不是枚举),只要能够确定节点(ATLEAST这就是我在我的小实验发现...)。 希望帮助...
嗯...我得到这个问题必须基于文件的印象。 即使我设置属性为SelectionLanguage,如果我使用一个枚举的XPath(我通过了使用Firefox XPather)节点对象仍然是空的。
有谁有一个想法可能是错了吗? xml文件附带一个Microsoft应用程序,因此应该是有效的。至少我在打开文件或在应用程序中使用它时没有任何问题,所以语法应该没问题。
抑或也许有人有一个VBScript函数,通过整个XML文件迭代来找到所需的节点,以删除吗?
请停止添加答案,就好像这是论坛讨论一样,*具有不同的范例。 – AnthonyWJones 2008-10-06 11:11:19
您的问题是,你有一个默认的命名空间。 XPath的默认名称空间始终是'无名'名称空间。
您需要: -
sNamespaces = "xmlns:cf='http://schemas.microsoft.com/SystemsManagementServer/2005/03/ConsoleFramework'"
objDOM.setProperty "SelectionNamespaces", sNamespaces
现在你可以在你的XPath使用: -
xPath = "/cf:SmsFormData/cf:Form/cf:Pages/cf:Page[@Id=""some Guid""]"
谢谢,但方括号需要删除。 - > objDOM.setPropery“SelectionNamespaces”,sNamespaces – Marcus 2008-10-06 11:33:25
不知道它对你是否有用,但我有类似的问题。
我有一个应用程序生成的XML文件,我需要管理。它的格式如下: <LoginData> <GeneralData> <LoginMask>65537</LoginMask> </GeneralData> <UserData> <User> <Username>TEST0</Username> ... </User> <User> <Username>TEST1</Username> ... </User> </UserData> </LoginData>
我需要匹配一个用户名并删除其他用户标签。
带我(是一个完整的XML小白)年龄去解决它,但最后我打一个节点上的匹配,并删除父节点的子:
在oXmlDoc每个x。 documentElement.selectSingleNode( “的UserData”)。的childNodes 如果x.getElementsByTagName( “用户名”)。项(0)的.text = “TEST1” 然后 组EXX = x.getElementsByTagName( “用户名”)。项(0) wscript.echo(x.getElementsByTagName( “用户名”)项目(0)的.text。) wScript.echo(x.nodename & “:” & x.text) x.parentNode.removeChild(X) 端如果 下一个
关于您尝试使用的xml示例的一些示例? – Kev 2008-10-06 09:50:20