在VB6中使用Sax解析编辑和编写XML

发布于 2024-11-08 16:38:54 字数 1796 浏览 0 评论 0原文

因此,我尝试使用 VB6 中的 SAX 解析(对于古老的 COM 组件)来编辑 xml(输出是 xml)。我更喜欢使用 DOM 解析,但 xml 的大小(可能超过 20MB)迫使我使用 SAX。我对 VB6 比较陌生,并且没有 SAX 解析经验。我在网上浏览过,但即使是我找到的最好的资源(http://www.developerfusion.com/article/84405/sax-and-vb-6/)也让我对如何将 grandchilren 标签与现有属性结合起来知之甚少为重命名的标签创建一个更长的属性。

我有基本的框架设置(如链接网站所示)。我想我也许可以将大部分繁重的工作限制为两个或三个子程序(_startDocument 中的前四行,使用 _startElement 获取描述标签,使用 endElement 将描述放入函数标签中)。然而,我缺乏 VB6/SAX 知识,这确实让我很受伤。任何帮助将不胜感激。

XML 现在如下所示;

<errordetails>
<error desc=”Count: 2”/>
<error desc=”System: System X”/>
<error desc=”Reason: Reason X”/>
   <functions>
      <function name=”x1” Description=”y1”>
         <violations count="2">
            <violation><source>admin</source><description>the first reason</description></violation>
            <violation><source>admin</source><description>the second reason</description></violation>
         </violations>  
      </function>
      <function name=”x2” Description=”y2”>
         <violations count="1">
           <violation><source>admin</source><description>another reason</description></violation>
        </violations>   
      </function>
   </functions>
</errordetails>

这是我想要的 xml 的样子;

<errordetails>
<error desc=”Count: 2”/>
<error desc=”System: System X”/>
<error desc=”Reason: Reason X”/>
<error desc=”FunctionName: x1, FunctionDescription: y1, FunctionReason: the first reason, FunctionReason: the second reason”/>
<error desc=”FunctionName: x2, FunctionDescription: y2, FunctionReason: another reason"/>
</errordetails>

So I am trying to edit an xml (output is an xml) using SAX parsing in VB6 (for an ancient COM component). I would prefer to use DOM parsing but the size of the xml (over 20MB's potentially) forces me to use SAX. I am relatively new to VB6 and I have no experience in SAX parsing. I have looked around online but even the best resource I have found (http://www.developerfusion.com/article/84405/sax-and-vb-6/) gives me little insight into how to combine grandchilren tags with existing attributes to make one longer attribute for a renamed tag.

I have the basic framework setup (as shown on the linked site). I think I might be able to limit most of the heavy lifting to two or three sub procedures (the first four lines in _startDocument, grab the description tag with _startElement, put the description into the function tag with endElement). However my lack of VB6/SAX knowledge is really hurting me here. Any help would be greatly appreciated.

Here is what the XML looks like Now;

<errordetails>
<error desc=”Count: 2”/>
<error desc=”System: System X”/>
<error desc=”Reason: Reason X”/>
   <functions>
      <function name=”x1” Description=”y1”>
         <violations count="2">
            <violation><source>admin</source><description>the first reason</description></violation>
            <violation><source>admin</source><description>the second reason</description></violation>
         </violations>  
      </function>
      <function name=”x2” Description=”y2”>
         <violations count="1">
           <violation><source>admin</source><description>another reason</description></violation>
        </violations>   
      </function>
   </functions>
</errordetails>

Here is what I want the xml to look like;

<errordetails>
<error desc=”Count: 2”/>
<error desc=”System: System X”/>
<error desc=”Reason: Reason X”/>
<error desc=”FunctionName: x1, FunctionDescription: y1, FunctionReason: the first reason, FunctionReason: the second reason”/>
<error desc=”FunctionName: x2, FunctionDescription: y2, FunctionReason: another reason"/>
</errordetails>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

她比我温柔 2024-11-15 16:38:54

您是否读过旧文章SAX 的乐趣:Visual Basic 示例?

很难告诉你更多。 SAX 实际上非常简单,您只需像处理任何 VB6 表单一样处理它,将其作为状态机即可。这意味着您将编写的大部分逻辑将管理状态,例如在通过事件向您提供转换后的数据时累积和发出转换后的数据。

Have you read things like the old article The Joy of SAX: a Visual Basic Sample?

It is hard to tell you much more. SAX is pretty simple really, you just need to approach it much as you should any VB6 Form, as a state machine. This means most of the logic you'll write will manage state, like accumulating and emitting transformed data as it is fed to you through the events.

笑,眼淚并存 2024-11-15 16:38:54

我忘了在我的问题中提及,如果某个函数的违规次数大于 20,我只希望前 20 个描述作为 FunctionReasons。
我在 sax 解析之外添加了前四行和最后一行。
我通过调用最后一个属性“Get XMLDoc_Function()”来获取另一个模块中的输出。
这是我得到的;

Option Explicit

Implements IVBSAXContentHandler

Dim m_oContentHandler As IVBSAXContentHandler
Dim m_wtr_Function As MXXMLWriter40
Dim m_oAttributes As MSXML2.SAXAttributes
Dim m_DOM As MSXML2.DOMDocument40

Dim m_sAttribute As String
Dim m_sFunctionName As String
Dim m_sFunctionDescription As String
Dim m_sFunctionReason As String
Dim m_sFunctionReasonCount As Integer

Dim isDescription As Boolean




Private Sub Class_Initialize()
    Set m_wtr_Function = New MXXMLWriter40
    m_wtr_Function.omitXMLDeclaration = True
    Set m_oContentHandler = m_wtr_Function
    Set m_DOM = New MSXML2.DOMDocument40
    m_DOM.setProperty "SelectionLanguage", "XPath"
    m_sFunctionReasonCount = 0
End Sub

Private Sub Class_Terminate()
    Set m_wtr_Function = Nothing
    Set m_oContentHandler = Nothing
    Set m_oAttributes = Nothing
    Set m_DOM = Nothing
End Sub

Private Sub IVBSAXContentHandler_characters(strChars As String)
    If isDescription Then
        If m_sFunctionReasonCount < 20 Then
            m_sFunctionReason = ", FunctionReason: " & strChars
            m_sAttribute = m_sAttribute & m_sFunctionReason
            m_sFunctionReasonCount = m_sFunctionReasonCount + 1
            isDescription = False
        End If
    End If
End Sub

Private Property Set IVBSAXContentHandler_documentLocator(ByVal RHS As MSXML2.IVBSAXLocator)

End Property

Private Sub IVBSAXContentHandler_endDocument()

End Sub

Private Sub IVBSAXContentHandler_endElement(strNamespaceURI As String, strLocalName As String, strQName As String)

    Select Case strQName
        Case "function"
            m_oAttributes.addAttribute "", "desc", "desc", "xs:string", m_sAttribute
            m_oContentHandler.startElement strNamespaceURI, "error", "error", m_oAttributes
            m_oContentHandler.endElement strNamespaceURI, "error", "error"
            m_sAttribute = ""
            m_sFunctionReasonCount = 0
    End Select

End Sub

Private Sub IVBSAXContentHandler_endPrefixMapping(strPrefix As String)

End Sub

Private Sub IVBSAXContentHandler_ignorableWhitespace(strChars As String)

End Sub

Private Sub IVBSAXContentHandler_processingInstruction(strTarget As String, strData As String)

End Sub

Private Sub IVBSAXContentHandler_skippedEntity(strName As String)

End Sub

Private Sub IVBSAXContentHandler_startDocument()

    m_oContentHandler.startDocument

End Sub



Private Sub IVBSAXContentHandler_startElement(strNamespaceURI As String, strLocalName As String, strQName As String, ByVal oAttributes As MSXML2.IVBSAXAttributes)

    Select Case strQName
        Case "functions"
            'do nothing

        Case "function"
            Set m_oAttributes = New SAXAttributes40
            m_sFunctionName = oAttributes.getValueFromQName("name")
            m_sAttribute = "FunctionName: " & m_sFunctionName
            m_sFunctionDescription = oAttributes.getValueFromQName("Description")
            m_sAttribute = m_sAttribute & ", FunctionDescription: " & m_sFunctionDescription

        Case "description"
            isDescription = True

    End Select

End Sub


Private Sub IVBSAXContentHandler_startPrefixMapping(strPrefix As String, strURI As String)

End Sub

Public Property Get XMLDoc_Function() As Variant
    XMLDoc_Function = m_wtr_Function.output
End Property

I forgot to mention in my question that if the number of violations for a function was greater than 20, I only wanted the first 20 descriptions as FunctionReasons.
I added the first four lines and the last line outside of the sax parsing.
I get the output in another module by calling the last property 'Get XMLDoc_Function()'.
Here is what I got;

Option Explicit

Implements IVBSAXContentHandler

Dim m_oContentHandler As IVBSAXContentHandler
Dim m_wtr_Function As MXXMLWriter40
Dim m_oAttributes As MSXML2.SAXAttributes
Dim m_DOM As MSXML2.DOMDocument40

Dim m_sAttribute As String
Dim m_sFunctionName As String
Dim m_sFunctionDescription As String
Dim m_sFunctionReason As String
Dim m_sFunctionReasonCount As Integer

Dim isDescription As Boolean




Private Sub Class_Initialize()
    Set m_wtr_Function = New MXXMLWriter40
    m_wtr_Function.omitXMLDeclaration = True
    Set m_oContentHandler = m_wtr_Function
    Set m_DOM = New MSXML2.DOMDocument40
    m_DOM.setProperty "SelectionLanguage", "XPath"
    m_sFunctionReasonCount = 0
End Sub

Private Sub Class_Terminate()
    Set m_wtr_Function = Nothing
    Set m_oContentHandler = Nothing
    Set m_oAttributes = Nothing
    Set m_DOM = Nothing
End Sub

Private Sub IVBSAXContentHandler_characters(strChars As String)
    If isDescription Then
        If m_sFunctionReasonCount < 20 Then
            m_sFunctionReason = ", FunctionReason: " & strChars
            m_sAttribute = m_sAttribute & m_sFunctionReason
            m_sFunctionReasonCount = m_sFunctionReasonCount + 1
            isDescription = False
        End If
    End If
End Sub

Private Property Set IVBSAXContentHandler_documentLocator(ByVal RHS As MSXML2.IVBSAXLocator)

End Property

Private Sub IVBSAXContentHandler_endDocument()

End Sub

Private Sub IVBSAXContentHandler_endElement(strNamespaceURI As String, strLocalName As String, strQName As String)

    Select Case strQName
        Case "function"
            m_oAttributes.addAttribute "", "desc", "desc", "xs:string", m_sAttribute
            m_oContentHandler.startElement strNamespaceURI, "error", "error", m_oAttributes
            m_oContentHandler.endElement strNamespaceURI, "error", "error"
            m_sAttribute = ""
            m_sFunctionReasonCount = 0
    End Select

End Sub

Private Sub IVBSAXContentHandler_endPrefixMapping(strPrefix As String)

End Sub

Private Sub IVBSAXContentHandler_ignorableWhitespace(strChars As String)

End Sub

Private Sub IVBSAXContentHandler_processingInstruction(strTarget As String, strData As String)

End Sub

Private Sub IVBSAXContentHandler_skippedEntity(strName As String)

End Sub

Private Sub IVBSAXContentHandler_startDocument()

    m_oContentHandler.startDocument

End Sub



Private Sub IVBSAXContentHandler_startElement(strNamespaceURI As String, strLocalName As String, strQName As String, ByVal oAttributes As MSXML2.IVBSAXAttributes)

    Select Case strQName
        Case "functions"
            'do nothing

        Case "function"
            Set m_oAttributes = New SAXAttributes40
            m_sFunctionName = oAttributes.getValueFromQName("name")
            m_sAttribute = "FunctionName: " & m_sFunctionName
            m_sFunctionDescription = oAttributes.getValueFromQName("Description")
            m_sAttribute = m_sAttribute & ", FunctionDescription: " & m_sFunctionDescription

        Case "description"
            isDescription = True

    End Select

End Sub


Private Sub IVBSAXContentHandler_startPrefixMapping(strPrefix As String, strURI As String)

End Sub

Public Property Get XMLDoc_Function() As Variant
    XMLDoc_Function = m_wtr_Function.output
End Property
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文