fengjie 发表于 2020-3-27 01:10:06

【已解决】请教如何解析XML文件的每条记录的属性的值?

本帖最后由 fengjie 于 2020-3-28 19:14 编辑

现有以下xml文档Example.xml<?xml version="1.0" encoding="UTF-8"?>
<lists version="0.1">
<record name="张三" age="25" birthday="19920811" qq="10000" phone="13800138000" />
<record name="李四" age="26" birthday="19910516" qq="10001" phone="13800138001" />
</lists>
根据rho123的XML通讯录的方法,由于本人水平有限,对XML的操作也不太理解,只能写到读出有几条记录,
Local $Title = "测试解析XML"
Local $XMLFile = @ScriptDir & "/Example.xml"

_ReadXML();读xml

Func _ReadXML();读xml
      $objXML = ObjCreate("Microsoft.XMLDOM")
      $sFile = $objXML.load($XMLFile)
      If Not $sFile Then
                MsgBox(16, $Title, "加载" & $XMLFile & "失败,文件不存在!!!")
      Else
                $objRootsite = $objXML.documentElement.selectSingleNode("//lists")
                $AllNodesNum = $objRootsite.childNodes.length
                $NodeOrder = $AllNodesNum - 1
                If $AllNodesNum < 1 Then
                        ConsoleWrite("没有找到任何记录!!" & @CRLF)
                        MsgBox(16, $Title, "没有找到任何记录!")
                Else
                        ConsoleWrite("共找到" & $AllNodesNum & "条记录!" & @CRLF)
                        MsgBox(64, $Title, "共找到" & $AllNodesNum & "条记录!")
                EndIf
      EndIf
EndFunc   ;==>_ReadXML
我现在的目的是想读出XML里每一条record记录的全部数据,以便利用其中的数据进行处理,最好能用_ArrayDisplay出来,请问该怎么写呢?
name="张三" age="25" birthday="19920811" qq="10000" phone="13800138000"看了好多个XML操作的例子,愣是看不出个所以然,水平有限,不得已来论坛求助,大佬勿见笑。



afan 发表于 2020-3-27 11:26:25

文本文档都可以用正则处理
#include <Array.au3>
Local $sSource = _
                '<?xml version="1.0" encoding="UTF-8"?>' & @CRLF & _
                '<lists version="0.1">' & @CRLF & _
                '<record name="张三" age="25" birthday="19920811" qq="10000" phone="13800138000" />' & @CRLF & _
                '<record name="李四" age="26" birthday="19910516" qq="10001" phone="13800138001" />' & @CRLF & _
                '</lists>'
;~MsgBox(0, '源字符串', $sSource)
Local $aSRE = StringRegExp($sSource, '(?mi)<record\h+name="(.*?)"[^"]+?"(.*?)"[^"]+?"(\d*)"[^"]+?"(\d*)"[^"]+?"(\d*)"\h*/>', 3)
_ArrayDisplay($aSRE, UBound($aSRE))

qxguoxing 发表于 2020-3-27 13:46:09

a大的正则方式不知是否满足你,下面是我的一个简单示例希望能帮到你
#include <WinAPIFiles.au3>
#include <GUIConstantsEx.au3>
#include <GuiEdit.au3>
#include <EditConstants.au3>
#include <FileConstants.au3>

Local $Poet = "" ;诗人
Local $PoemName = "" ;诗名
Local $Poetry = "" ;诗

#Region ;读取xml文件内容
Local $SourceFile = @WorkingDir & "\Test.xml"
Local $objXML = ObjCreate("Microsoft.XMLDOM")
Local $xFile = $objXML.load($SourceFile)
If Not $xFile Then
        MsgBox(16, "错误", "加载" & $SourceFile & "失败,文件不存在!!!")
        Exit
Else
        Local $PoetryNode = $objXML.selectSingleNode("/root/poetry[@id='one']")
        If $PoetryNode.attributes.length > 0 Then
                $Poet = $PoetryNode.attributes.getNamedItem("poet").text
                $PoemName = $PoetryNode.attributes.getNamedItem("poemname").text
                $Poetry = $objXML.selectSingleNode("/root/poetry[@id='one']").text
        Else
                MsgBox(16, "提示信息", "没有内容")
        EndIf
       
EndIf
#EndRegion ;读取xml文件内容

Local $hGUI = GUICreate("ReadOrWriteXML", 400, 300)
GUICtrlCreateLabel("诗名 :", 60, 10, 390, 20)
Local $InputPoemName = GUICtrlCreateInput($PoemName, 100, 10, 200, 20)
GUICtrlCreateLabel("作者 :", 60, 50, 390, 20)
Local $InputPoet = GUICtrlCreateInput($Poet, 100, 50, 200, 20)
GUICtrlCreateLabel("诗 :", 60, 100, 390, 20)
Local $EditPoetry = GUICtrlCreateEdit($Poetry, 100, 100, 200, 100)

Local $BtnSave=GUICtrlCreateButton("保存",100, 260, 200, 20)

GUISetState(@SW_SHOW, $hGUI)

While 1
        Switch GUIGetMsg()
                Case $BtnSave
                        SaveAccountPassword("Save")
                       
                Case $GUI_EVENT_CLOSE
                        ExitLoop
                       
        EndSwitch
WEnd


Func SaveAccountPassword($IsShow)
        Local $PoetryNode = $objXML.selectSingleNode("/root/poetry[@id='one']")
        $PoetryNode.attributes.getNamedItem("poet").text = GUICtrlRead($InputPoet)
        $PoetryNode.attributes.getNamedItem("poemname").text = GUICtrlRead($InputPoemName)
        $PoetryNode.text = GUICtrlRead($EditPoetry)
        $objXML.Save($SourceFile)
        If @error == 0 Then
                MsgBox("-1", "提示信息", "保存成功", 10)
        Else
                MsgBox("-1", "提示信息", "保存失败", 10)
        EndIf
EndFunc   ;==>SaveAccountPassword

;xml文件格式
<?xml version="1.0"?>
<root>
        <poetry id="one" poet="李白" poemname="静夜思">床前明月光,疑是地上霜。
举头望明月,低头思故乡。</poetry>
</root>

fengjie 发表于 2020-3-27 18:15:06

afan 发表于 2020-3-27 11:26
文本文档都可以用正则处理

谢谢A版,正则很强大,我完全看不懂呀。

想改也不懂如何改,然后貌似不是我想要的效果。

我是想读出来之后是以下这样的:

然后用循环一次读一行数据(一条记录)
另外我的xml文件大小可能有20M+,
不知这样用fileopen的方式打开后正则匹配的速度如何?

fengjie 发表于 2020-3-27 18:16:42

qxguoxing 发表于 2020-3-27 13:46
a大的正则方式不知是否满足你,下面是我的一个简单示例希望能帮到你
#include
#include


谢谢!不知道是否可以不指定id,直接把全部数据用循环一条一条读出来?

afan 发表于 2020-3-27 19:00:19

fengjie 发表于 2020-3-27 18:15
谢谢A版,正则很强大,我完全看不懂呀。

想改也不懂如何改,然后貌似不是我想要的效果。


正则的数组需要按自己的需求整理
#include <Array.au3>
Local $sSource = _
                '<?xml version="1.0" encoding="UTF-8"?>' & @CRLF & _
                '<lists version="0.1">' & @CRLF & _
                '<record name="张三" age="25" birthday="19920811" qq="10000" phone="13800138000" />' & @CRLF & _
                '<record name="李四" age="26" birthday="19910516" qq="10001" phone="13800138001" />' & @CRLF & _
                '</lists>'
;~ MsgBox(0, '源字符串', $sSource)
Local $aSRE = StringRegExp($sSource, '(?mi)<record\h+name="(.*?)"[^"]+?"(.*?)"[^"]+?"(\d*)"[^"]+?"(\d*)"[^"]+?"(\d*)"\h*/>', 3)
;~ _ArrayDisplay($aSRE, UBound($aSRE))
Local $a2D, $iX = 0
For $ii = 0 To UBound($aSRE) - 1 Step 5
        For $jj = 0 To 4
                $a2D[$iX][$jj] = $aSRE[$ii + $jj]
        Next
        $iX += 1
Next
_ArrayDisplay($a2D)

fengjie 发表于 2020-3-27 22:04:39

afan 发表于 2020-3-27 19:00
正则的数组需要按自己的需求整理
谢谢!这正是我想要的效果。
我照葫芦画瓢改了一下表达式:
(?mi)<record\h+name="(.*?)"[^"]+?"(.*?)"[^"]+?"(.*?)"[^"]+?"(.*?)"[^"]+?"(.*?)"\h*/>终于能实现我想要的功能了。
看来得好好学习正则表达式。
不过还是想知道XML的DOM方法怎么实现

页: [1]
查看完整版本: 【已解决】请教如何解析XML文件的每条记录的属性的值?