Использование Set QuestionNodes = oXMLFile.SelectNodes("/catalog/query/question/text()")
для списка вопросов затрудняет фильтрацию, чем это необходимо.Проще использовать список узлов запроса и затем обращаться к дочерним узлам по мере необходимости.
Итак, если вы хотите перечислить все узлы, используйте:
Dim queryNodes As IXMLDOMNodeList
' ...
Set queryNodes = oXmlFile.SelectNodes("/catalog/query")
и вызатем можно работать со значениями дочерних узлов, например, так:
Dim node As IXMLDOMNode
For Each node In queryNodes
Debug.Print "Q: " & node.SelectSingleNode("question").Text & vbCrLf & _
"A: " & node.SelectSingleNode("answer").Text & vbCrLf & _
"C: " & node.SelectSingleNode("comment").Text & vbCrLf & _
"G: " & node.SelectSingleNode("genre").Text & vbCrLf & vbCrLf
Next node
Если затем вы хотите работать только с узлами, где жанр "SCPC", тогда это просто случай изменения queryNodes
list, например:
Set queryNodes = oXmlFile.SelectNodes("/catalog/query[genre='SCPC']")
Код для доступа к дочерним узлам не меняется только потому, что мы отфильтровали список по-другому.Все изменения содержатся в том, как мы создаем список queryNodes
.Код для обновления queryNodes
можно вызвать из обработчика событий для выпадающего списка, который позволяет пользователю выбрать жанр.
Мы могли бы адаптировать код для печати всех значений узла в подпрограмму, которая печатаетзначения определенного узла (как это было предложено Тимом Уильямсом в комментариях):
Sub printNode(node As IXMLDOMNode)
Debug.Print "Q: " & node.SelectSingleNode("question").Text & vbCrLf & _
"A: " & node.SelectSingleNode("answer").Text & vbCrLf & _
"C: " & node.SelectSingleNode("comment").Text & vbCrLf & _
"G: " & node.SelectSingleNode("genre").Text & vbCrLf & vbCrLf
End Sub
Чтобы контролировать, какой узел отображается через ваш интерфейс, используйте свойство Item
из списка queryNodes
.Первый узел - queryNodes.Item(0)
, следующий - queryNodes.Item(1)
и т. Д.
Если мы используем переменную с именем position
для отслеживания того, где мы находимся в списке, тогда кнопка Previous в вашем интерфейседолжно составить position = position - 1
, а ваша кнопка «Далее» - position = position + 1
.
Итак, когда пользователь нажмет «Предыдущий» или «Далее», мы обновим position
и затем вызовем printNode queryNodes.Item(position)
.Всегда есть вероятность того, что мы вышли за пределы начала или конца списка, и это можно проверить с помощью If Not queryNodes.Item(position) Is Nothing
, прежде чем мы попытаемся вызвать printNode
.
. Для вашего конкретного случая вы бынужна подпрограмма для заполнения полей в вашем интерфейсе.Для этого переименуйте printNode
в loadNode
и вместо печати в окне отладки скопируйте соответствующий текст из каждого дочернего узла в соответствующее поле в вашем интерфейсе.
Функция saveNode
будеттолько наоборот: скопируйте значение каждого поля в вашем интерфейсе в текстовое свойство соответствующего дочернего узла