2008-10-06 94 views
0

我遇到了无法选择需要删除的特定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对象是空的。该节点未被选中,但为什么?

+0

关于您尝试使用的xml示例的一些示例? – Kev 2008-10-06 09:50:20

回答

2

这是一个默认的命名空间的问题。尝试包括您在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也很有用。

0

鉴于以下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将帮助你)。

0

感谢您的快速回复!这无疑作品在简单的情况,但这并不在我的具体情况:(

因此,因此让详谈工作:

根节点: 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提示!我一直在使用它尝试,但不幸的是它的枚举方式:/

+0

您应该真的编辑您的问题以包含这些详细信息 – AnthonyWJones 2008-10-06 11:10:12

0

你需要使用

objDOM.SetProperty“SelectionLanguage”设置选择语言的XPath“的XPath”

一旦设置这个属性就可以使用完整的XPath来访问任何元素,你想

0

如果您有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这就是我在我的小实验发现...)。 希望帮助...

0

嗯...我得到这个问题必须基于文件的印象。 即使我设置属性为SelectionLanguage,如果我使用一个枚举的XPath(我通过了使用Firefox XPather)节点对象仍然是空的。

有谁有一个想法可能是错了吗? xml文件附带一个Microsoft应用程序,因此应该是有效的。至少我在打开文件或在应用程序中使用它时没有任何问题,所以语法应该没问题。

抑或也许有人有一个VBScript函数,通过整个XML文件迭代来找到所需的节点,以删除吗?

+0

请停止添加答案,就好像这是论坛讨论一样,stackoverflow具有不同的范例。 – AnthonyWJones 2008-10-06 11:11:19

0

您的问题是,你有一个默认的命名空间。 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""]" 
+0

谢谢,但方括号需要删除。 - > objDOM.setPropery“SelectionNamespaces”,sNamespaces – Marcus 2008-10-06 11:33:25

0

不知道它对你是否有用,但我有类似的问题。

我有一个应用程序生成的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) 端如果 下一个

相关问题