我遇到的问题是我无法选择需要删除的特定XML节点。我已经尝试通过使用XPath来选择节点,XPath适用于某些XML文件,但我无法找到更复杂文件中节点的正确XPath。
是否有人知道可以加载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“
子节点:表单
属性: Id =“某些GUID”CustomData =“某些数据”FormType =“某种类型”ForceRefresh =“false”
子/节点页面
儿童/儿童/儿童节点页面
属性: VendorId =“VendorName”Id =“some GUID”Assembly =“dll文件名”Namespace =“some Namespace”Type =“some Type”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 :(得分: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也很有用。
答案 1 :(得分: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
...返回字符串“value2”:根据您的需要,您可能需要稍微调整一下(再次,像Visual XPath这样的工具,或任何好的XPath reference将帮助您)。
答案 2 :(得分: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“
子节点:表单
属性: Id =“某些GUID”CustomData =“某些数据”FormType =“某种类型”ForceRefresh =“false”
子/节点 页
儿童/儿童/儿童节点页面
<强>属性:强>厂商ID = “VENDORNAME” ID = “一些GUID” 大会= “DLL文件名” 命名空间= “一些命名空间” 类型= “一些类型” 的helpID = “” &GT;
我选择此特定页面的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对象是空的。该节点未被选中,但为什么?
哦,顺便说一句:感谢Visual XPath提示!我尝试过使用它但不幸的是它采用了枚举方式:/
答案 3 :(得分:0)
您需要使用
将选择语言设置为XPathobjDOM.SetProperty“SelectionLanguage”,“XPath”
设置此属性后,您可以使用完整的XPath访问所需的任何元素
答案 4 :(得分:0)
如果你有Firefox浏览器,你可以简单地安装DOM Inspector(仅适用于Firefox 3.0)和XPather扩展。然后,您可以在DOM Inspector窗口中遍历所需的节点,相应的XPath将显示在同一窗口的XPather工具栏中。
DOM Inspector:https://addons.mozilla.org/en-US/firefox/addon/6622
XPather:https://addons.mozilla.org/en-US/firefox/addon/1192?id=1192
XPather似乎尽可能使用属性(而不是枚举)来识别节点(至少这是我在我的小实验中发现的......)。 希望有所帮助...
答案 5 :(得分:0)
嗯,......我得到的印象是问题必须是基于文件的。 即使我为SelectionLanguage设置了属性,如果我使用枚举的XPath(我使用FireFox XPather获得),节点对象仍然是空的。
有人知道可能出现什么问题吗? xml文件附带Microsoft应用程序,因此应该有效。至少我在打开文件或在应用程序中使用它时没有任何问题,所以语法应该没问题。
或者也许某人有一个vbscript函数遍历整个xml文件以找到所需的节点以便删除它?
答案 6 :(得分: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""]"
答案 7 :(得分:0)
不确定它是否对您有用,但我遇到了类似的问题。
我有一个应用程序生成的XML文件,我需要管理。它的格式是:
<LoginData>
<GeneralData>
<LoginMask>65537</LoginMask>
</GeneralData>
<UserData>
<User>
<Username>TEST0</Username>
...
</User>
<User>
<Username>TEST1</Username>
...
</User>
</UserData>
</LoginData>
我需要匹配用户名并删除其他用户标记。
让我(作为一个完整的XML noob)年龄来解决它,但最后我在节点上匹配,并删除父节点的子节点:
对于oXmlDoc.documentElement.selectSingleNode(“UserData”)中的每个x,.childNodes if x.getElementsByTagName(“Username”)。item(0).text =“TEST1”then set exx = x.getElementsByTagName(“Username”)。item(0) wscript.echo(x.getElementsByTagName( “用户名”)。项(0)的.text) wScript.echo(x.nodename&amp;“:”&amp; x.text) x.parentNode.removeChild(x)的 万一 下