2008-10-06 2 views
0

У меня возникла проблема с тем, что я не могу выбрать конкретный узел XML, который необходимо удалить. Я уже пытался выбрать узел, используя XPath, который отлично подходит для некоторых файлов XML, но я не могу понять правильный XPath для узла в более сложном файле.Как удалить определенный узел в файле XML с помощью vbscript

Кто-нибудь знает бесплатный инструмент, который может загружать 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 = "ложь"

Детский/Детский узел: Страницы

Ребенок/Ребенок/Детский узел: Page

Атрибуты: VendorID = "Имя_вендора" Id = "некоторые GUID" Assembly = "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""" 

Вы затем использовать этот cf префикс в вашем XPath например:

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 = "значение" в качестве селектора).

Что касается инструмента для генерации запросов, подобных этому автоматически, метка с именем Visual XPath должна делать трюк, и она бесплатна (она даже поставляется с исходным кодом на C#).

Редактировать после просмотра постеру: эта форма выбора XPath также подходит для «простых случаев», как и для самых сложных документов. Вы, do, должны убедиться, что ваше выражение 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 "

Детский узел: Форма

Атрибуты: Id = "некоторые GUID" CustomData = "Некоторые данные" FormType = "некоторый тип" ForceRefresh = "ложь"

Детский/Детский узел: Страницы

Ребенок/Ребенок/узел Ребенок: Page

Атрибуты: VendorID = "Имя_вендора" Id = "некоторые GUID" Как sembly = "DLL имя файла" Пространство имен = "некоторые пространство имен" Тип = "некоторый тип" HelpID = "">

Мое выражение XPath для выбора этой конкретной страницы теперь будет:

XPATH = «/ SmsFormData/Форма/Страницы/страница [@ Id = "некоторые 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

Вам нужно установить Выбор языка для использования XPath

objDOM.SetProperty «SelectionLanguage», «XPath»

После того, как вы установили это свойство вы можете использовать полный XPath для доступа к любым элементам, которые вы хотите

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, кажется, использует атрибуты (а не перечисления) всякий раз, когда это возможно, чтобы идентифицировать узлы (по крайней мере, это то, что я нашел в моем маленьком экспериментирования ...). Надеюсь, что это поможет ...

0

Хм, ... У меня создается впечатление, что проблема должна быть основана на файлах. Даже если я устанавливаю свойство для SelectionLanguage, и если я использую перечисленный XPath (который я получил с помощью FireFox XPather), узел Object по-прежнему остается пустым.

Есть ли у кого-нибудь идеи, что может быть неправильным? Файл xml поставляется с приложением Microsoft и поэтому должен быть действительным. По крайней мере, у меня нет проблем при открытии файла или его использовании в приложении, поэтому синтаксис должен быть в порядке.

Возможно, у кого-то есть функция vbscript, которая выполняет итерацию через весь XML-файл, чтобы найти нужный узел, чтобы удалить его?

+0

Пожалуйста, прекратите добавлять ответы, как если бы это была дискуссия на форуме, у stackoverflow есть другая парадигма. – AnthonyWJones 2008-10-06 11:11:19

0

Проблема заключается в том, что у вас есть пространство имен по умолчанию. По умолчанию пространство имен XPaths - это пространство имен без имени.

Вам нужно: -

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. documentElement.selectSingleNode ("UserData"). childNodes , если 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 & ":" & x.text) x.parentNode.removeChild (х) конец, если next