VBA перебирает узлы XML и получает значения внутри каждого узла

#xml #vba #loops #ms-access #nodes

Вопрос:

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

 <manifest identifier="MANIFEST1">
  <organizations />
  <resources>  
    <resource identifier="AMS_EDDC7208" type="imsqti_xmlv1p2p1" href="a1231.xml"> 
      <metadata> 
        <schema>abc123</schema>
        <schemaversion>1.2</schemaversion>
        <metadata> 
          <exmetadata>
            <exmetadataSection identifier="841" name="Topic">
              <description>
              </description>
              <exmetadataparameterSet>
                <param name="Topic" type="String">Math</param>
                <param name="Gender" type="String">N</param>
                <param name="Race" type="String">Z</param>
                <param name="Difficulty Level" type="String">HARD</param>
              </exmetadataparameterSet>
              <exdependencysection identifierref="" /> 
            </exmetadataSection>
            <exmetadataSection identifier="842" name="Math Reasoning">
              <description>
              </description>
              <exmetadataparameterSet>
                <param name="Item_Type" type="String">A</param>
                <param name="Cont1" type="String">ARI</param>
                <param name="Cont2" type="String">REM</param>
                <param name="Cognitive" type="String">PUR</param>
              </exmetadataparameterSet>
              <exdependencysection identifierref="" />
            </exmetadataSection>
          </exmetadata>
        </metadata>
      </metadata>
      <file href="a1231.xml" />
    </resource>
  <resources>  
    <resource identifier="AMS_AB3dC7208" type="imsqti_xmlv1p2p1" href="a1232.xml"> 
      <metadata> 
        <schema>abc123</schema>
        <schemaversion>1.2</schemaversion>
        <metadata> 
          <exmetadata>
            <exmetadataSection identifier="841" name="Topic">
              <description>
              </description>
              <exmetadataparameterSet>
                <param name="Topic" type="String">Math</param>
                <param name="Gender" type="String">N</param>
                <param name="Race" type="String">Z</param>
                <param name="Difficulty Level" type="String">HARD</param>
              </exmetadataparameterSet>
              <exdependencysection identifierref="" /> 
            </exmetadataSection>
            <exmetadataSection identifier="842" name="Math Reasoning">
              <description>
              </description>
              <exmetadataparameterSet>
                <param name="Item_Type" type="String">A</param>
                <param name="Cont1" type="String">GEO</param>
                <param name="Cont2" type="String">ABS</param>
                <param name="Cognitive" type="String">PUR</param>
              </exmetadataparameterSet>
              <exdependencysection identifierref="" />
            </exmetadataSection>
          </exmetadata>
        </metadata>
      </metadata>
      <file href="a1232.xml" />
    </resource>  
  <resources>  
    <resource identifier="AMS_EE0023DC7208" type="imsqti_xmlv1p2p1" href="a1233.xml"> 
      <metadata> 
        <schema>abc123</schema>
        <schemaversion>1.2</schemaversion>
      </metadata>
      <file href="a1233.xml" />
    </resource>  
  <resources>  
    <resource identifier="AMS_XXZDF2323CC208" type="imsqti_xmlv1p2p1" href="a1234.xml"> 
      <metadata> 
        <schema>abc123</schema>
        <schemaversion>1.2</schemaversion>
        <metadata> 
          <exmetadata>
            <exmetadataSection identifier="841" name="Topic">
              <description>
              </description>
              <exmetadataparameterSet>
                <param name="Topic" type="String">Math</param>
                <param name="Gender" type="String">N</param>
                <param name="Race" type="String">Z</param>
                <param name="Difficulty Level" type="String">HARD</param>
              </exmetadataparameterSet>
              <exdependencysection identifierref="" /> 
            </exmetadataSection>
            <exmetadataSection identifier="842" name="Math Reasoning">
              <description>
              </description>
              <exmetadataparameterSet>
                <param name="Item_Type" type="String">A</param>
                <param name="Cont1" type="String">ALG</param>
                <param name="Cont2" type="String">APP</param>
                <param name="Cognitive" type="String">REA</param>
              </exmetadataparameterSet>
              <exdependencysection identifierref="" />
            </exmetadataSection>
          </exmetadata>
        </metadata>
      </metadata>
      <file href="a1234.xml" />
    </resource>          
</manifest>
 

Я могу перебирать узлы ресурсов и получать идентификатор и текст href для каждого узла, но у меня возникают проблемы с получением правильных сведений от узлов параметров, когда я просматриваю каждый из узлов ресурсов. Мне нужны только определенные значения параметров, поэтому я пытался использовать SelectSingleNode, но понимаю, что это даст мне только первый набор, с которым он столкнется.

 Dim XDoc, nodesThatMatter  As Object
Dim strFieldName, strESID, strFile, strTopic, strItemType, strCont1, strCont2, strCognitive As String
Set XDoc = CreateObject("MSXML2.DOMDocument")
XDoc.async = False: XDoc.validateOnParse = False
XDoc.Load (Me.FileIn)

Set nodesThatMatter = XDoc.SelectNodes("//resource")
   
For Each node In nodesThatMatter
    
    'resource identifier
    strESID = node.Attributes.Item(0).Text
    'resource file
    strFile = node.Attributes.Item(2).Text
            
    strTopic = node.SelectSingleNode("//param[@name='Topic']").Text
    strItemType = node.SelectSingleNode("//param[@name='Item_Type']").Text
    strCont1 = node.SelectSingleNode("//param[@name='Cont1']").Text
    strCont2 = node.SelectSingleNode("//param[@name='Cont2']").Text
    strCognitive = node.SelectSingleNode("//param[@name='Cognitive']").Text
              
         
Next node
 
Set XDoc = Nothing
 

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

Ответ №1:

Я закончил тем, что углубился в childnodes и смог добраться до того, что мне было нужно. Все еще задаетесь вопросом, есть ли более прямой способ сделать это, перейдя непосредственно на определенный уровень по имени?