我对所有这些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
NUMBER1
数字2
number3 number4
number3的
number4
我想要的是以某种方式摆脱斜体字。
我在子程序中使用递归,因为它是如何需要的。但是,当我检查子节点和要打印的节点值时,我最终会得到所有子节点及其自身没有特定值的节点的值。
我知道我可以使用baseName手动跳过节点,但这不是我正在寻找的。如果可以使用它自己的功能或可能适用于任何此类情况的更通用的功能,那就太好了。
感谢您的帮助!
编辑:(我现在的代码)
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
答案 0 :(得分:1)
如果我理解正确,你想忽略具有
的节点<c>
和<f>
中的。
我发现的唯一技巧是直接处理XML。
因此,我们首先搜索只有节点<c>
和<f>
但没有其他节点的唯一参数。因此我发现了这个规则:
这意味着在<c>
和<f>
之后,会有另一个以<
开头的标记。
如果我们看一下<c>
获得的节点Node.xml
的XML代码,它看起来像:
<c>
<d>number1</d>
<e>number2</e>
<f>
<g>number3</g>
<h>number4</h>
</f>
</c>
为了便于处理,我们将换行符,制表符和空格展平,所以我们最终在这里:
<c><d>number1</d><e>number2</e><f><g>number3</g><h>number4</h></f></c>
现在我们只需要检查第一个节点标记<c>
是否直接,然后是另一个以<
开头的标记。因此,我们找到第一个>
并查看它是否后跟<
。如果这是真的,那么节点可以省略,因为它没有属性也没有文本。
我们在PrintNodeValue
过程中执行所有操作,然后开始声明变量并获取实际处理的节点的原始XML代码:
Dim xml as String
xml = Node.xml
我们将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>
我们删除了第一个标记
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
产生......
东西
东西
NUMBER1
数字2
number3的
number4
请注意,您可能需要将vbCrLf
更改为vbCr
或vbLf
,具体取决于哪个系统,例如。 Windows,Linux或Mac XML文件最初来自(它们使用不同的换行符)。为了安全起见,您还可以删除所有3。
xml = Replace(xml, vbCrLf, vbNullString)
xml = Replace(xml, vbCr, vbNullString)
xml = Replace(xml, vbLf, vbNullString)