Извлечение нескольких дочерних узлов из нескольких родительских узлов

#excel #xml #vba

#excel #xml #vba

Вопрос:

У меня возникли некоторые проблемы с извлечением узлов, которые указаны ниже, друг другу. Я предпочитаю не выполнять цикл с for each node через родительские узлы, потому что реальный XML-файл очень большой со многими дочерними узлами. Я надеюсь, что есть другой способ, аналогичный тому, что я уже делаю.

Я хочу распечатать рецепт RECIPE_LABEL_STRING/text() с внутренними вложенными рецептами SUB_DATA/ID/text() Проблема в том, что существует несколько рецептов с разными вложенными рецептами, и то, как я это делаю сейчас, я получаю все вложенные рецепты, прикрепленные к родительскому рецепту. Мне нужно «исправить» первый elt внутри SelecNodes . Возможно ли это?

Мой код:

 Dim wb As Workbook
Set wb = ThisWorkbook
Dim oXMLFile As Object

        Set oXMLFile = CreateObject("Microsoft.XMLDOM")
        XMLFileName = ("C:UsersxDesktopNodeSearch.xml")
        
        If XMLFileName = "" Then
            MsgBox "No XML found"
            Exit Sub
            Else
        End If

        If oXMLFile.Load(XMLFileName) Then
           'MsgBox "Loaded successfully"
        Else
          Exit Sub
        End If
        
        
        Set RecipeID = oXMLFile.SelectNodes("/ADEL:Definitions/RecipeCollection/RECIPE_NUMBER/RECIPE_DATA/elt/RECIPE_LABEL_STRING/text()")
        Set SubRecipeID = oXMLFile.SelectNodes("/ADEL:Definitions/RecipeCollection/RECIPE_NUMBER/RECIPE_DATA/elt/LAYER_DATA/elt/LAYER_SUB_DATA/SUB_DATA/ID/text()")
       
            Row = 2
                
            For i = 0 To RecipeID.Length - 1
                            
                wb.Sheets("Sheet1").Cells(Row, 1) = RecipeID(i).NodeValue
                
                    For s = 0 To SubRecipeID.Length - 1
                                
                    wb.Sheets("Sheet1").Cells(Row, 2) = 
SubRecipeID(s).NodeValue
                    Row = Row   1
                                  
                    Next
                
                Row = Row   1
                              
            Next
  

файл XML:

 <?xml version="1.0" encoding="utf-8"?>
<!-- Automatically generated XML file -->
<ADEL:Definitions xmlns:ADEL="http://XMLSchema/MT/TWIN/ADEL/v6.2.1" 
xmlns:ADELrap="http://XMLSchema/MT/TWIN/ADEL/v6.2.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema- 
instance" xsi:schemaLocation="http://XMLSchema/MT/TWIN/ADEL/v6.2.1 ADEL.xsd">
 <RecipeCollection>
   <UnitRecipe></UnitRecipe>
    <RECIPE_NUMBER>
      <RECIPE_DATA>
        <elt>
          <RECIPE_LABEL_STRING>Recipe 1</RECIPE_LABEL_STRING>
          <LAYER_DATA>
            <elt>
              <LAYER_SUB_DATA>
                <SUB_DATA>
                  <ID>Sub Recipe 1</ID>
                </SUB_DATA>
              </LAYER_SUB_DATA>
            </elt>
             <elt>
              <LAYER_SUB_DATA>
                <SUB_DATA>
                  <ID>Sub Recipe 2</ID>
                </SUB_DATA>
              </LAYER_SUB_DATA>
            </elt>
          </LAYER_DATA>
        </elt>
        <elt>
          <RECIPE_LABEL_STRING>Recipe 2</RECIPE_LABEL_STRING>
          <LAYER_DATA>
            <elt>
              <LAYER_SUB_DATA>
                <SUB_DATA>
                  <ID>Sub Recipe 1</ID>
                </SUB_DATA>
              </LAYER_SUB_DATA>
            </elt>
            <elt>
              <LAYER_SUB_DATA>
                <SUB_DATA>
                  <ID>Sub Recipe 2</ID>
                </SUB_DATA>
              </LAYER_SUB_DATA>
            </elt>
            <elt>
              <LAYER_SUB_DATA>
                <SUB_DATA>
                  <ID>Sub Recipe 3</ID>
                </SUB_DATA>
              </LAYER_SUB_DATA>
            </elt>
          </LAYER_DATA>
        </elt>
        <elt>
          <RECIPE_LABEL_STRING>Recipe 3</RECIPE_LABEL_STRING>
           <LAYER_DATA>
            <elt>
              <LAYER_SUB_DATA>
                <SUB_DATA>
                  <ID>Sub Recipe 3</ID>
                </SUB_DATA>
              </LAYER_SUB_DATA>
            </elt>
          </LAYER_DATA>
        </elt>
      </RECIPE_DATA>
    </RECIPE_NUMBER>
  </RecipeCollection>
</ADEL:Definitions>
  

И изображение того, как он печатается сейчас:
введите описание изображения здесь

Ответ №1:

Попробуйте это решение сверху вниз

         Dim RecipeID As Object, SubRecipeID As Object
        Set RecipeID = oXMLFile.SelectNodes( _
            "/ADEL:Definitions/RecipeCollection/RECIPE_NUMBER/RECIPE_DATA/elt/RECIPE_LABEL_STRING")
       
       With Sheet1                      ' using a sheet's Code(Name)
            Dim i As Long, r As Long: r = 1
            For i = 0 To RecipeID.Length - 1
                r = r   1
                .Cells(r, 1) = RecipeID(i).Text
                ' build XPath string starting from RecipeID(i) node's parent :-)
                Set SubRecipeID = RecipeID(i).ParentNode.SelectNodes("LAYER_DATA/elt/LAYER_SUB_DATA/SUB_DATA/ID")
                
                Dim ii As Long
                For ii = 0 To SubRecipeID.Length - 1
                    .Cells(r, 2) = SubRecipeID(ii).Text
                    r = r   1
                Next ii
            Next
        End With

  

Комментарии:

1. Ага, большое спасибо, это было именно то, что я искал. Я много чего перепробовал, чтобы прикрепить родительские узлы, но никогда бы не понял этого. 🙂