[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖

[文本处理] 【已解决】求助批处理从一堆XML中提取所有关键词写到一个csv中

本帖最后由 zhengwei007 于 2024-11-21 21:19 编辑

我有N个XML碎文件,文件名各式各样,但无所谓,我希望把这些文件内容全部整理到一个csv中,我就挑几个例子展示,大概样式如下:
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <list xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../xsd/items.xsd">
  3. <item id="1" type="Weapon" name="Short Sword">
  4. <set name="icon" val="icon.weapon_small_sword_i00" />
  5. <set name="bodypart" val="rhand" />
  6. <set name="weight" val="1600" />
  7. <set name="soulshots" val="1" />
  8. <set name="spiritshots" val="1" />
  9. <set name="crystal_type" val="none" />
  10. <set name="p_dam" val="8" />
  11. <set name="rnd_dam" val="10" />
  12. <set name="weapon_type" val="sword" />
  13. <set name="critical" val="8" />
  14. <set name="atk_speed" val="379" />
  15. <set name="m_dam" val="6" />
  16. <set name="price" val="768" />
  17. <for>
  18. <set val="8" order="0x08" stat="pAtk" />
  19. <set val="6" order="0x08" stat="mAtk" />
  20. <set val="8" order="0x08" stat="rCrit" />
  21. <add val="0" order="0x10" stat="accCombat" />
  22. <set val="379" order="0x08" stat="pAtkSpd" />
  23. <enchant val="0" order="0x0C" stat="pAtk" />
  24. <enchant val="0" order="0x0C" stat="mAtk" />
  25. </for>
  26. </item>
  27. <item id="2" type="Weapon" name="Long Sword">
  28. <set name="icon" val="icon.weapon_long_sword_i00" />
  29. <set name="bodypart" val="rhand" />
  30. <set name="weight" val="1560" />
  31. <set name="soulshots" val="2" />
  32. <set name="spiritshots" val="2" />
  33. <set name="crystal_type" val="none" />
  34. <set name="p_dam" val="24" />
  35. <set name="rnd_dam" val="10" />
  36. <set name="weapon_type" val="sword" />
  37. <set name="critical" val="8" />
  38. <set name="atk_speed" val="379" />
  39. <set name="m_dam" val="17" />
  40. <set name="price" val="136000" />
  41. <for>
  42. <set val="24" order="0x08" stat="pAtk" />
  43. <set val="17" order="0x08" stat="mAtk" />
  44. <set val="8" order="0x08" stat="rCrit" />
  45. <add val="0" order="0x10" stat="accCombat" />
  46. <set val="379" order="0x08" stat="pAtkSpd" />
  47. <enchant val="0" order="0x0C" stat="pAtk" />
  48. <enchant val="0" order="0x0C" stat="mAtk" />
  49. </for>
  50. </item>
  51. <item id="6" type="Weapon" name="Apprentice's Wand">
  52. <set name="icon" val="icon.weapon_apprentices_wand_i00" />
  53. <set name="bodypart" val="rhand" />
  54. <set name="weight" val="1350" />
  55. <set name="soulshots" val="1" />
  56. <set name="spiritshots" val="1" />
  57. <set name="crystal_type" val="none" />
  58. <set name="p_dam" val="5" />
  59. <set name="rnd_dam" val="20" />
  60. <set name="weapon_type" val="blunt" />
  61. <set name="critical" val="4" />
  62. <set name="hit_modify" val="4.00000" />
  63. <set name="atk_speed" val="379" />
  64. <set name="m_dam" val="7" />
  65. <set name="price" val="138" />
  66. <set name="sellable" val="false" />
  67. <set name="dropable" val="false" />
  68. <set name="tradeable" val="false" />
  69. <for>
  70. <set val="5" order="0x08" stat="pAtk" />
  71. <set val="7" order="0x08" stat="mAtk" />
  72. <set val="4" order="0x08" stat="rCrit" />
  73. <add val="4" order="0x10" stat="accCombat" />
  74. <set val="379" order="0x08" stat="pAtkSpd" />
  75. <enchant val="0" order="0x0C" stat="pAtk" />
  76. <enchant val="0" order="0x0C" stat="mAtk" />
  77. </for>
  78. </item>
  79. <item id="7" type="Weapon" name="Apprentice's Rod">
  80. <set name="icon" val="icon.weapon_apprentices_rod_i00" />
  81. <set name="bodypart" val="rhand" />
  82. <set name="weight" val="1330" />
  83. <set name="soulshots" val="1" />
  84. <set name="spiritshots" val="1" />
  85. <set name="crystal_type" val="none" />
  86. <set name="p_dam" val="6" />
  87. <set name="rnd_dam" val="20" />
  88. <set name="weapon_type" val="blunt" />
  89. <set name="critical" val="4" />
  90. <set name="hit_modify" val="4.00000" />
  91. <set name="atk_speed" val="379" />
  92. <set name="m_dam" val="8" />
  93. <set name="price" val="768" />
  94. <for>
  95. <set val="6" order="0x08" stat="pAtk" />
  96. <set val="8" order="0x08" stat="mAtk" />
  97. <set val="4" order="0x08" stat="rCrit" />
  98. <add val="4" order="0x10" stat="accCombat" />
  99. <set val="379" order="0x08" stat="pAtkSpd" />
  100. <enchant val="0" order="0x0C" stat="pAtk" />
  101. <enchant val="0" order="0x0C" stat="mAtk" />
  102. </for>
  103. </item>
  104. <item id="8" type="Weapon" name="Willow Staff">
  105. <set name="icon" val="icon.weapon_willow_staff_i00" />
  106. <set name="bodypart" val="lrhand" />
  107. <set name="weight" val="1080" />
  108. <set name="soulshots" val="1" />
  109. <set name="spiritshots" val="1" />
  110. <set name="crystal_type" val="none" />
  111. <set name="p_dam" val="11" />
  112. <set name="rnd_dam" val="20" />
  113. <set name="weapon_type" val="bigblunt" />
  114. <set name="critical" val="4" />
  115. <set name="hit_modify" val="4.00000" />
  116. <set name="atk_speed" val="325" />
  117. <set name="m_dam" val="12" />
  118. <set name="price" val="12500" />
  119. <for>
  120. <set val="11" order="0x08" stat="pAtk" />
  121. <set val="12" order="0x08" stat="mAtk" />
  122. <set val="4" order="0x08" stat="rCrit" />
  123. <add val="4" order="0x10" stat="accCombat" />
  124. <set val="325" order="0x08" stat="pAtkSpd" />
  125. <enchant val="0" order="0x0C" stat="pAtk" />
  126. <enchant val="0" order="0x0C" stat="mAtk" />
  127. </for>
  128. </item>
  129. <item id="99" type="Weapon" name="Apprentice's Spellbook">
  130. <set name="icon" val="icon.weapon_apprentices_spellbook_i00" />
  131. <set name="bodypart" val="rhand" />
  132. <set name="weight" val="650" />
  133. <set name="soulshots" val="1" />
  134. <set name="spiritshots" val="1" />
  135. <set name="crystal_type" val="none" />
  136. <set name="p_dam" val="9" />
  137. <set name="rnd_dam" val="10" />
  138. <set name="weapon_type" val="etc" />
  139. <set name="critical" val="8" />
  140. <set name="atk_speed" val="379" />
  141. <set name="m_dam" val="12" />
  142. <set name="price" val="12500" />
  143. <for>
  144. <set val="9" order="0x08" stat="pAtk" />
  145. <set val="12" order="0x08" stat="mAtk" />
  146. <set val="8" order="0x08" stat="rCrit" />
  147. <add val="0" order="0x10" stat="accCombat" />
  148. <set val="379" order="0x08" stat="pAtkSpd" />
  149. <enchant val="0" order="0x0C" stat="pAtk" />
  150. <enchant val="0" order="0x0C" stat="mAtk" />
  151. </for>
  152. </item>
  153. <item id="9208" type="Armor" name="Phantom Mask (Event)">
  154. <!-- A feathered hair accessory. This item cannot be exchanged or dropped. -->
  155. <set name="icon" val="icon.accessary_mask_of_chaotic_i00" />
  156. <set name="bodypart" val="dhair" />
  157. <set name="armor_type" val="none" />
  158. <set name="weight" val="10" />
  159. <set name="crystal_type" val="none" />
  160. <set name="sellable" val="false" />
  161. <set name="dropable" val="false" />
  162. <set name="tradeable" val="false" />
  163. <for>
  164. <add val="0" order="0x10" stat="pDef" />
  165. </for>
  166. </item>
  167. </list>
复制代码
通过批处理输出结果如下:
  1. id,type,name,icon,bodypart,armor_type,weight,soulshots,spiritshots,crystal_type,p_dam,rnd_dam,weapon_type,critical,hit_modify,atk_speed,m_dam,price,sellable,dropable,tradeable,pAtk,mAtk,rCrit,accCombat,pAtkSpd,pAtk,mAtk,pDef
  2. 1,Weapon,Short Sword,icon.weapon_small_sword_i00,rhand,,1600,1,1,none,8,10,sword,8,,379,6,768,,,,8,6,8,0,379,0,0,
  3. 2,Weapon,Long Sword,icon.weapon_long_sword_i00,rhand,,1560,2,2,none,24,10,sword,8,,379,17,136000,,,,24,17,8,0,379,0,0,
  4. 6,Weapon,Apprentice's Wand,icon.weapon_apprentices_wand_i00,rhand,,1350,1,1,none,5,20,blunt,4,4,379,7,138,FALSE,FALSE,FALSE,5,7,4,4,379,0,0,
  5. 99,Weapon,Apprentice's Spellbook,icon.weapon_apprentices_spellbook_i00,rhand,,650,1,1,none,9,10,etc,8,,379,12,12500,,,,9,12,8,0,379,0,0,
  6. 9208,Armor,Phantom Mask (Event),icon.accessary_mask_of_chaotic_i00,dhair,none,10,,,none,,,,,,,,,FALSE,FALSE,FALSE,,,,,,,,0
复制代码
里面遇到新的字段时,直接增加到列标题上,没有该数据的,值为空。
每个[item]为一段,for里面是把后面的做为标题,前面的val才是值。
不知有没有大佬帮忙看看好不好做这个批处理。先谢谢各位!

powershell

TOP

本帖最后由 czjt1234 于 2024-11-20 21:30 编辑

pAtk,mAtk,rCrit,accCombat,pAtkSpd,pAtk,mAtk,pDef
输出结果,第一行最后为什么有2个pAtk,mAtk
你处理csv的程序怎么分辨这2个相同的数据?

ID为7和8的为什么不输出?

QQ 20147578

TOP

  1. <set val="9" order="0x08" stat="pAtk" />
  2. <set val="12" order="0x08" stat="mAtk" />
  3. <enchant val="0" order="0x0C" stat="pAtk" />
  4. <enchant val="0" order="0x0C" stat="mAtk" />
复制代码
虽然是2个,但是意义不太一样,只要所有的字段顺序对了就行,一样不一样对我来说无所谓。
我想要一个通用版本的批处理,以后用别的XML文件,我只需要简单修改这个批处理里面的关键词就能通用,要不一旦变了,我还得来求助。

TOP

本帖最后由 czjt1234 于 2024-11-20 21:49 编辑

你举例的这文件,有29个字段
那别的xml文件里会不会有新的字段?

是每个xml各输出一个csv,还是所有xml合并输出到一个csv?

QQ 20147578

TOP

for描述里的装备效果不止一个 ,有set 有add,有enchant,说不定可能还有sub ,div或者其他什么的
这样一来csv列数根本就不明 ,怎么弄???这能弄么???

TOP

本帖最后由 aloha20200628 于 2024-11-21 00:16 编辑

回复 1# zhengwei007

以下代码针对一楼示例样本 1.xml,结果文件为 new.xml,假定同名字段(如 pAtk,mAtk)共在一个节点内(如 <for ... >)
  1. @echo off &setlocal enabledelayedexpansion
  2. set "lst=,item id, type, name,icon,bodypart,armor_type,weight,soulshots,spiritshots,crystal_type,p_dam,rnd_dam,weapon_type,critical,hit_modify,atk_speed,m_dam,price,sellable,dropable,tradeable,pAtk,mAtk,rCrit,accCombat,pAtkSpd,pAtk1,mAtk1,pDef,"
  3. set "v=!lst!"
  4. (echo,item,type,name,icon,bodypart,armor_type,weight,soulshots,spiritshots,crystal_type,p_dam,rnd_dam,weapon_type,critical,hit_modify,atk_speed,m_dam,price,sellable,dropable,tradeable,pAtk,mAtk,rCrit,accCombat,pAtkSpd,pAtk1,mAtk1,pDef
  5. for /f tokens^=1-7^delims^=^ ^<^=^" %%a in (
  6.    'findstr /rbi /c:" *.*=\"^" /c:" ^</item^>" "1.xml" ') do (
  7.    if /i "%%a"=="item id" (
  8.        set "v=!v:%%a,=%%b,!"&set "v=!v:%%c,=%%d,!"&set "v=!v:%%e,=%%f,!"
  9.    ) else if "%%e"==" />" (set "v=!v:%%b,=%%d,!"
  10.    ) else if "%%g"==" />" (
  11.        set "go=1"&for %%s in ("%%f","%%f1") do if defined go if "!v:%%~s,=%%b,!" neq "!v!" (
  12.        set "go="&set "v=!v:%%~s,=%%b,!")
  13.    ) else if /i "%%a"=="/item>" ((for %%s in (!lst!) do set "v=!v:,%%s,=,,!")&echo,!v:~1,-1!&set "v=!lst!")
  14. ))>"new.xml"
  15. endlocal&pause&exit/b
复制代码

TOP

你举例的这文件,有29个字段
那别的xml文件里会不会有新的字段?

是每个xml各输出一个csv,还是所有xml ...
czjt1234 发表于 2024-11-20 21:42


你好,我希望每个XML合到一个文件中。
对于重复字段,只启前面的,后面enchant的直接过滤掉。

TOP

回复  zhengwei007

以下代码针对一楼示例样本 1.xml,结果文件为 new.xml,假定同名字段(如 pAtk,mAtk ...
aloha20200628 发表于 2024-11-21 00:14


您好,程序报错了,提示如下:
  1. FINDSTR: 无法打开 1.xml
  2. 请按任意键继续...
复制代码
我的文件名怎么起的都有,如0000-0099.xml,2900-2999.xml,9200-9299.xml 这种的

TOP

请提供2个或2个以上需要处理的xml文件,不要修改,直接上传到网盘中,便于大家测试用。

TOP

链接: https://pan.baidu.com/s/1wrnrL-sqME6kMGqtb58ULQ
提取码: 3w3r
复制这段内容后打开百度网盘手机App,操作更方便哦

谢谢,这是全内容。

TOP

回复 1# zhengwei007

将以下脚本以ansi编码格式保存为xml2csv.awk,下载gawk( http://bcn.bathome.net/tool/4.1.0/gawk.exe ),执行gawk -fxml2csv.awk *.xml>out.csv
  1. BEGIN {
  2. FS = "\""
  3. }
  4. /^[ \t]*<item id=.+>[ \t]*$/, /^[ \t]*<\/item>[ \t]*$/ {
  5. if (/^[ \t]*<item id=.+>[ \t]*$/) {
  6. nnn++
  7. id_[nnn, "id"] = $2
  8. type_[nnn, "type"] = $4
  9. name_[nnn, "name"] = $6
  10. }
  11. if (/^[ \t]*<set name=".+" val=".+".+\/>[ \t]*$/) {
  12. if (! ($2 in d_id)) {
  13. id_n++
  14. d_id[$2] = id_n
  15. }
  16. dat_[nnn, $2] = $4
  17. }
  18. if (/^[ \t]*<for>[ \t]*$/) {
  19. for_id = 1
  20. }
  21. if (/^[ \t]*<\/for>[ \t]*$/) {
  22. for_id = 0
  23. }
  24. if (for_id) {
  25. if (/^[ \t]*<.+val=".+" order=".+" stat=".+".+\/>[ \t]*$/) {
  26. if (! ($6 in d_id)) {
  27. id_n++
  28. d_id[$6] = id_n
  29. }
  30. dat_[nnn, $6] = $2
  31. }
  32. }
  33. }
  34. END {
  35. PROCINFO["sorted_in"] = "@val_num_asc"
  36. printf "%s,%s,%s", "id", "type", "name"
  37. for (j in d_id) {
  38. printf ",%s", j
  39. }
  40. print ""
  41. for (i = 1; i <= nnn; i++) {
  42. printf "%s,%s,%s", id_[i, "id"], type_[i, "type"], name_[i, "name"]
  43. for (j in d_id) {
  44. printf ",%s", dat_[i, j]
  45. }
  46. print ""
  47. }
  48. }
复制代码

TOP

本帖最后由 czjt1234 于 2024-11-21 11:58 编辑
  1. rem 另存为 ANSI 编码 bat
  2. ' & cls & cscript.exe /nologo /e:vbscript "%~f0" %* & pause & exit /b
  3. Option Explicit
  4. Dim p, a, b, c, e, d, f, i, v, oDOMDocument, oWshShell, oFSO
  5. p = "."               '当前路径。可以指定其它路径,比如 d:\test\
  6. e = "id,type,name"    '固定字段
  7. a = "name"            '属性名
  8. b = "val"             '属性值
  9. c = "stat"            '属性名
  10. d = "val"             '属性值
  11. Set oDOMDocument = CreateObject("Msxml2.DOMDocument")
  12. Set oWshShell = CreateObject("WScript.Shell")
  13. Set oFSO = CreateObject("Scripting.FileSystemObject")
  14. p = oFSO.GetAbsolutePathName(p)
  15. oWshShell.CurrentDirectory = p
  16. For Each i In oFSO.GetFolder(p).Files
  17.     If LCase(oFSO.GetExtensionName(i)) = LCase("xml") Then
  18.         f = ""
  19.         v = ""
  20.         Call t(i.Path)
  21.     End If
  22. Next
  23. Sub t(ByVal file)
  24.     Dim s, i, x, a0, a1, f1, f2, oNode, oXMLDOMSelection
  25.     oDOMDocument.load file
  26.     If oDOMDocument.parseError.errorCode <> 0 Then
  27.         wsh.Echo i & vbCrLf & oDOMDocument.parseError.reason _
  28.                  & "第 " & oDOMDocument.parseError.line & " 行"
  29.         wsh.Quit()
  30.     End If
  31.     x = ".//*[@" & a & " and @" & b & "]"
  32.     f1 = ","
  33.     For Each oNode In oDOMDocument.documentElement.childNodes
  34.         Set oXMLDOMSelection = oNode.SelectNodes(x)
  35.         For Each i In oXMLDOMSelection
  36.             s = i.nodeName & "_" & i.getAttribute(a) & ","
  37.             If InStr(f1, "," & s ) = 0 Then f1 = f1 & s
  38.         Next
  39.     Next
  40.     f1 = Left(f1, Len(f1) - 1)
  41.     f1 = Right(f1, Len(f1) - 1)
  42.     f2 = ","
  43.     x = ".//*[@" & c & " and @" & d & "]"
  44.     For Each oNode In oDOMDocument.documentElement.childNodes
  45.         Set oXMLDOMSelection = oNode.SelectNodes(x)
  46.         For Each i In oXMLDOMSelection
  47.             s = i.nodeName & "_" & i.getAttribute(c) & ","
  48.             If InStr(f2, "," & s ) = 0 Then f2 = f2 & s
  49.         Next
  50.     Next
  51.     If f2 = "," Then
  52.         f = e & "," & f1
  53.     Else
  54.         f2 = Left(f2, Len(f2) - 1)
  55.         f2 = Right(f2, Len(f2) - 1)
  56.         f = e & "," & f1 & "," & f2
  57.     End If
  58.     For Each oNode In oDOMDocument.documentElement.childNodes
  59.         For Each i In Split(e, ",")
  60.             v = v & oNode.getAttribute(i) & ","
  61.         Next
  62.         For Each i In Split(f1, ",")
  63.             a0 = Split(i, "_")(0)
  64.             a1 = Split(i, "_", 2)(1)
  65.             x = ".//" & a0 & "[@" & a & " = '" & a1 & "']"
  66.             Set oXMLDOMSelection = oNode.SelectNodes(x)
  67.             If oXMLDOMSelection.length = 0 Then
  68.                 x = ""
  69.             Else
  70.                 x = oXMLDOMSelection(0).getAttribute(b)
  71.                 If InStr(x, ",") Then x = """" & x & """"
  72.             End If
  73.             v = v & x & ","
  74.         Next
  75.         For Each i In Split(f2, ",")
  76.             If f2 = "," Then Exit For
  77.             a0 = Split(i, "_")(0)
  78.             a1 = Split(i, "_", 2)(1)
  79.             x = ".//" & a0 & "[@" & c & " = '" & a1 & "']"
  80.             Set oXMLDOMSelection = oNode.SelectNodes(x)
  81.             If oXMLDOMSelection.length = 0 Then
  82.                 x = ""
  83.             Else
  84.                 x = oXMLDOMSelection(0).getAttribute(d)
  85.                 If InStr(x, ",") Then x = """" & x & """"
  86.             End If
  87.             v = v & x & ","
  88.         Next
  89.         v = Left(v, Len(v) - 1) & vbCrLf
  90.     Next
  91.     s = oFSO.GetBaseName(file) & ".csv"
  92.     oFSO.OpenTextFile(s, 2, True).Write f & vbCrLf & v
  93.     wsh.Echo s
  94. End Sub
复制代码

QQ 20147578

TOP

小批量测试,发现有些name字段存在逗号,将name字段使用双引号来屏蔽,以避免干扰列的显示。
  1. @echo off
  2. set TableHeader=id,type,name,icon,bodypart,armor_type,weight,soulshots,spiritshots,crystal_type,p_dam,rnd_dam,weapon_type,critical,hit_modify,atk_speed,m_dam,price,sellable,dropable,tradeable,pAtk,mAtk,rCrit,accCombat,pAtkSpd,pAtk,mAtk,pDef
  3. for %%i in (%TableHeader%) do set _%%i=true
  4. (echo,%TableHeader%
  5. setlocal enabledelayedexpansion
  6. for /f tokens^=1-6^ delims^=^"^=^ %%1 in ('type *.xml 2^>nul^|findstr "<item </item> <set <add"') do (
  7.     if "%%1"=="<item id" (
  8.         set "id=%%2"
  9.         set "type=%%4"
  10.         set "name="%%6""
  11.     ) else (
  12.         if defined _%%2 (
  13.             set %%2=%%4
  14.         ) else if defined _%%6 (
  15.             set %%6=%%2
  16.         ) else if "%%1"=="</item>" (
  17.             for %%i in (%TableHeader%) do (
  18.                 if defined str (set str=!str!,!%%i!) else set str=!%%i!
  19.                 set %%i=
  20.             )
  21.         echo,!str!
  22.         set str=
  23.         )
  24.     )
  25. ))>1.csv
  26. pause
复制代码

TOP

回复 13# czjt1234


除了固定字段,其它字段名前面加了节点名,再有重复就不管了
比如
set_pAtk,set_mAtk,enchant_pAtk,enchant_mAtk

QQ 20147578

TOP

返回列表