MSXML Remove Node ведет себя не так, как ожидалось

Я пытаюсь удалить узел из следующего XML. Данные ниже представляют только актуальные данные:

<StaffMembers>
    <Staff Name="Test1" Date="Date1"/>
    <Staff Name="Test2" Date="Date2"/>
</StaffMembers>

Мой код выглядит следующим образом:

Sub DeleteRecord(strName as string, strDate as string)

'Load Document

    Set xList = xDoc.SelectNodes("//StaffMembers/")
    for each xNode in xList
             If xNode.Attributes.Length > 0 And xNode.Attributes.getNamedItem("Date").NodeValue = strDate Then
                 xnode.parentnode.removechild xnode
                 exit for
             End if
    next xNode

'Save Document

End Sub

Результирующий XML - как видите, он неполный:

<StaffMembers>
    <Staff Name="Test1" Date="Date1"/>
    <Staff Name="Tes

Правильный узел выбран, но удален лишь частично. Если я открою полученный XML в Блокноте, часть текста узла останется. Кто-нибудь может это объяснить?

Редактировать:

Я попытался удалить каждый атрибут по отдельности, прежде чем удалять элемент. Это страдает от той же проблемы.

Спасибо


person Jiminy Cricket    schedule 12.09.2014    source источник
comment
не могли бы вы опубликовать соответствующую часть неправильного вывода с учетом фрагмента XML, который вы разместили в качестве ввода   -  person har07    schedule 12.09.2014
comment
Вопрос отредактирован. Спасибо   -  person Jiminy Cricket    schedule 12.09.2014


Ответы (3)


Вы можете использовать XPath для выбора узлов с соответствующими критериями атрибутов. Например :

.....
Set xList = xDoc.SelectNodes("//StaffMembers/Staff[@Date='Date2']")
For Each xnode In xList
    xnode.ParentNode.RemoveChild xnode
Next xnode
.....
person har07    schedule 12.09.2014
comment
Спасибо. Теперь я попытался установить значение в список и попытался выбрать один узел, но у меня та же проблема. Он выбирает правильный узел, но не удаляет его полностью. Кажется, тут что-то другое. - person Jiminy Cricket; 12.09.2014
comment
Не могли бы вы попробовать использовать другой XML, который содержит только ту часть, которую вы разместили в вопросе, проблема остается? В любом случае, трудно диагностировать дальше, не имея возможности воспроизвести проблему. - person har07; 12.09.2014
comment
Да, я использовал образец XML, и у меня та же проблема - это очень запутанно. - person Jiminy Cricket; 12.09.2014
comment
Если вы закомментируете/удалите коды, удаляющие узлы, проблема останется? Я почему-то подозреваю, что это не логика удаления узлов, которые были неправильными, может быть, это просто то, как вы сохраняете измененный XML или как вы отображаете результат - person har07; 12.09.2014

Вот селектор XPath, который выберет узлы с именами Test2 или Test3:

xDoc.SelectNodes("//Staff[@Name = ""Test2"" || @Name = ""Test3""]")

Для тестовой программы VBScript ниже я получаю следующий вывод после удаления этих узлов:

<StaffMembers>
  <Staff Name="Test1" Date="Date1"/>
  <Staff Name="Test4" Date="Date4"/>
</StaffMembers>

Программа тестирования:

Option Explicit

DeleteRecord "Test2", "Test3"

Sub DeleteRecord(name1, name2)
    Dim xDoc : Set xDoc = CreateObject("Msxml2.DOMDocument")
    xDoc.LoadXML GetXml()

    Dim xList : Set xList = xDoc.SelectNodes _
        ("//Staff[@Name = """ & name1 & """ || @Name = """ & name2 & """]")

    Dim xNode
    For Each xNode in xList
        xNode.ParentNode.RemoveChild xNode
    Next

    WScript.Echo xDoc.Xml
End Sub

Function GetXml()
    Dim NL : NL = vbNewLine

    GetXmL = _
        "<StaffMembers>" &NL& _
        "  <Staff Name='Test1' Date='Date1'/>" &NL& _
        "  <Staff Name='Test2' Date='Date2'/>" &NL& _
        "  <Staff Name='Test3' Date='Date3'/>" &NL& _
        "  <Staff Name='Test4' Date='Date4'/>" &NL& _
        "</StaffMembers>"
End Function
person DavidRR    schedule 12.09.2014
comment
Привет Дэвид, спасибо за ответ. Приведенный выше код работает в вашей тестовой программе, но не переводится в мою. Я могу подтвердить, что выбран правильный узел - я добился этого с помощью Debug. Print BaseName и Attributes, чтобы быть уверенным. ParentNode определенно является «StaffMemebers», а BaseName и атрибуты идеально совпадают. Можете ли вы придумать какую-либо причину, по которой он удаляет странные части XML? Я не могу понять, почему он удаляет закрывающие теги Корня, например - person Jiminy Cricket; 12.09.2014
comment
Спасибо, это имеет смысл. Можете ли вы указать мне направление документации XPath, чтобы выбрать узел с определенным значением атрибута? - person Jiminy Cricket; 12.09.2014
comment
Еще одно наблюдение: DeleteRecord не использует свой аргумент strName. - person DavidRR; 12.09.2014
comment
Я упростил XML и Sub из-за конфиденциальных данных. Он используется в полной подпрограмме. - person Jiminy Cricket; 12.09.2014
comment
Я еще раз пересмотрел свою тестовую программу, чтобы показать удаление нескольких элементов без необходимости прибегать к временному массиву. По общему признанию, мой ответ показывает, что возможно, но не объясняет искажение, которое вы видите при изучении полученного вывода XML. - person DavidRR; 12.09.2014

Спасибо за ответы. Мне удалось сузить проблему до медленного сетевого подключения. Повреждение не происходит при сохранении в локальную папку.

Спасибо

person Jiminy Cricket    schedule 15.09.2014