是否有可能跳过Excel VBA中的XML文件中的节点?

对于所有这些XML和VBA,我都是新手。 我诚实地根据我对oop的了解做所有的事情,但是我正在处理的当前项目需要在VBA中完成。
我到处寻找,但找不到,也想不出有什么实际的办法可以做我现在要做的事情,所以如果有可能的话,我在这里请求大家的知识。

所以基本上我有一个这样的XML文件:

<a name="something" > <b name="something"> <c> <d>number1</d> <e>number2</e> <f> <g>number3</g> <h>number4</h> </f> </c> </b> </a> 

我的问题是我需要在Excel工作表中生成XML的内容。 我知道如何做到这一点,然而,我最终得到的是这样的:

某物
某物
number1 number2 number3 number4
1号
2号
number3 number4
number3的
号码4

我想要的是以某种方式摆脱斜体的行。

我在子程序中使用recursion,因为这是如何需要的。 但是,当我检查子节点和要打印的节点值时,我最终会得到所有子节点以及它们自己没有特定值的节点值。

我知道我可以使用baseName手动跳过节点,但这不是我正在寻找的。 如果有可能使它自己的function或更一般的东西可以适用于这种情况发生,将是很好的。

感谢您的帮助!

编辑:(我现在的代码)

 Sub Main() Dim XDoc As MSXML2.DOMDocument Set XDoc = New MSXML2.DOMDocument Set mainWorkBook = ActiveWorkbook mainWorkBook.Sheets("Sheet1").Clear Dim point As IXMLDOMSelection Filename = ThisWorkbook.Worksheets("Sheet1").Range("A1").Value XDoc.Load (Filename) Set point = XDoc.SelectNodes("/*") Call ProcessChildNodes(point(0)) End Sub Sub PrintNodeValue(Node As IXMLDOMNode) If (Node.Attributes.Length = 0) Then Row = Row + 1 mainWorkBook.Sheets("Sheet1").Cells(Row, 1).Value = Node.Text End If End Sub Sub PrintAttributesValue(Node As IXMLDOMNode) If (Node.Attributes.Length <> 0) Then Row = Row + 1 For j = Node.Attributes.Length - 1 To 0 Step -1 strng = Node.Attributes.Length mainWorkBook.Sheets("Sheet1").Cells(Row, strng - j).Value = Node.Attributes(j).Text Next End If End Sub Sub ProcessChildNodes(Node As IXMLDOMNode) If (Node.HasChildNodes) Then For m = 0 To Node.ChildNodes.Length - 1 If Node.ChildNodes(m).NodeType <> NODE_TEXT Then Call PrintNodeValue(Node.ChildNodes(m)) Call PrintAttributesValue(Node.ChildNodes(m)) Call ProcessChildNodes(Node.ChildNodes(m)) End If Next Else End If End Sub 

如果我正确地理解了你,你想忽略已经有的节点

  • 没有文字input
  • 没有属性

在你的例子<c><f>


我发现的唯一技巧是直接处理XML。 所以我们首先search一个唯一的参数,只有节点<c><f>有但没有其他节点。 所以我find了这个规则:

  1. 节点不能有一个属性
  2. 该节点必须由另一个节点直接(没有文本)

这意味着在<c><f>之后直接有另一个以<开头的标签。

理论

  1. 如果我们看一下Node.xml获取的node <c>的XML代码,它看起来像:

     <c> <d>number1</d> <e>number2</e> <f> <g>number3</g> <h>number4</h> </f> </c> 
  2. 为了更容易处理,我们将换行符,制表符和空格展平,所以我们最终在这里:

     <c><d>number1</d><e>number2</e><f><g>number3</g><h>number4</h></f></c> 
  3. 现在我们只需要检查第一个节点标记<c>是否紧接着另一个以<开始的标记。 因此我们find第一个> ,看它是否跟着< 。 如果这是真的,那么节点可以省略,因为它没有属性,也没有文本。

让我们开始编码

  1. 我们在PrintNodeValue过程中做所有事情,并开始声明一个variables并获取实际处理的节点的原始XML代码:

     Dim xml as String xml = Node.xml 
  2. 我们将这个xml弄平,并删除所有换行符,制表符和空格

     xml = Replace(xml, vbCrLf, vbNullString) xml = Replace(xml, vbTab, vbNullString) xml = Replace(xml, " ", vbNullString) 

    xml现在是<c><d>number1</d><e>number2</e><f><g>number3</g><h>number4</h></f></c>

  3. 我们删除第一个标签

     xml = Right(xml, Len(xml) - InStr(1, xml, ">")) 

    并看看我们的2条规则(没有属性,并跟着另一个标签直接适用)

     If (Node.Attributes.Length = 0) And Left(xml, 1) <> "<" Then 

所以我们最终…

 Sub PrintNodeValue(Node As IXMLDOMNode) Dim xml As String xml = Node.xml 'get raw xml xml = Replace(xml, vbCrLf, vbNullString) 'strip off line breaks xml = Replace(xml, vbTab, vbNullString) 'strip off tabs xml = Replace(xml, " ", vbNullString) 'strip off spaces xml = Right(xml, Len(xml) - InStr(1, xml, ">")) 'strip off first tag If (Node.Attributes.Length = 0) And Left(xml, 1) <> "<" Then 'check our 2 rules iRow = iRow + 1 mainWorkBook.Sheets("Sheet1").Cells(iRow, 1).Value = Node.Text End If End Sub 

这产生…

某物
某物
1号
2号
number3的
号码4

请注意,您可能需要将vbCrLf更改为vbCrvbLf具体取决于哪个系统,例如。 Windows,Linux或Mac的XML文件最初来自(他们使用不同的换行符)。 为了安全,你也可以删除所有3。

 xml = Replace(xml, vbCrLf, vbNullString) xml = Replace(xml, vbCr, vbNullString) xml = Replace(xml, vbLf, vbNullString)