Board logo

标题: [问题求助] 如何根据xml文件的结构来生成对应的文件夹 [打印本页]

作者: 5i365    时间: 2022-3-12 12:21     标题: 如何根据xml文件的结构来生成对应的文件夹

本帖最后由 5i365 于 2022-3-12 13:10 编辑

这是另一个贴子的反向生成, http://www.bathome.net/redirect. ... 1826&pid=252441 went大侠在贴子的最后已经成功搞定, 再次感谢!

期待高手一展身手, 提前感谢!

XML文件内容如下:
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <opml version="1.0"
  3.     xmlns:sx="http://www.microsoft.com/schemas/rss/sse">
  4.     <head>
  5.         <title>顶级</title>
  6.     </head>
  7.     <body>
  8.         <outline text="一级1">
  9.             <outline text="二级1">
  10.                 <outline text="三级1">
  11.                     <outline text="四级1"></outline>
  12.                     <outline text="四级2"></outline>
  13.                 </outline>
  14.                 <outline text="三级2">
  15.                     <outline text="四级1"></outline>
  16.                     <outline text="四级2"></outline>
  17.                 </outline>
  18.             </outline>
  19.             <outline text="二级2">
  20.                 <outline text="三级1">
  21.                     <outline text="四级1"></outline>
  22.                     <outline text="四级2"></outline>
  23.                 </outline>
  24.                 <outline text="三级2">
  25.                     <outline text="四级1"></outline>
  26.                     <outline text="四级2"></outline>
  27.                 </outline>
  28.             </outline>
  29.         </outline>
  30.         <outline text="一级2">
  31.             <outline text="二级1">
  32.                 <outline text="三级1">
  33.                     <outline text="四级1"></outline>
  34.                     <outline text="四级2"></outline>
  35.                 </outline>
  36.                 <outline text="三级2">
  37.                     <outline text="四级1"></outline>
  38.                     <outline text="四级2"></outline>
  39.                 </outline>
  40.             </outline>
  41.             <outline text="二级2">
  42.                 <outline text="三级1">
  43.                     <outline text="四级1"></outline>
  44.                     <outline text="四级2"></outline>
  45.                 </outline>
  46.                 <outline text="三级2">
  47.                     <outline text="四级1"></outline>
  48.                     <outline text="四级2"></outline>
  49.                 </outline>
  50.             </outline>
  51.         </outline>
  52.         <outline text="一级3">
  53.             <outline text="二级1">
  54.                 <outline text="三级1">
  55.                     <outline text="四级1"></outline>
  56.                     <outline text="四级2"></outline>
  57.                 </outline>
  58.                 <outline text="三级2">
  59.                     <outline text="四级1"></outline>
  60.                     <outline text="四级2"></outline>
  61.                 </outline>
  62.             </outline>
  63.             <outline text="二级2">
  64.                 <outline text="三级1">
  65.                     <outline text="四级1"></outline>
  66.                     <outline text="四级2"></outline>
  67.                 </outline>
  68.                 <outline text="三级2">
  69.                     <outline text="四级1"></outline>
  70.                     <outline text="四级2"></outline>
  71.                 </outline>
  72.             </outline>
  73.         </outline>
  74.     </body>
  75. </opml>
复制代码
最终要生成的文件夹结构如下:
  1. C:\USERS\ADMINISTRATOR\DESKTOP\顶级
  2. ├─一级1
  3. │  ├─二级1
  4. │  │  ├─三级1
  5. │  │  │  ├─四级1
  6. │  │  │  └─四级2
  7. │  │  │
  8. │  │  └─三级2
  9. │  │      ├─四级1
  10. │  │      └─四级2
  11. │  └─二级2
  12. │      ├─三级1
  13. │      │  ├─四级1
  14. │      │  └─四级2
  15. │      └─三级2
  16. │          ├─四级1
  17. │          └─四级2
  18. ├─一级2
  19. │  ├─二级1
  20. │  │  ├─三级1
  21. │  │  │  ├─四级1
  22. │  │  │  └─四级2
  23. │  │  └─三级2
  24. │  │      ├─四级1
  25. │  │      └─四级2
  26. │  └─二级2
  27. │      ├─三级1
  28. │      │  ├─四级1
  29. │      │  └─四级2
  30. │      └─三级2
  31. │          ├─四级1
  32. │          └─四级2
  33. └─一级3
  34.     ├─二级1
  35.     │  ├─三级1
  36.     │  │  ├─四级1
  37.     │  │  └─四级2
  38.     │  └─三级2
  39.     │      ├─四级1
  40.     │      └─四级2
  41.     └─二级2
  42.         ├─三级1
  43.         │  ├─四级1
  44.         │  └─四级2
  45.         └─三级2
  46.             ├─四级1
  47.             └─四级2
复制代码

作者: 5i365    时间: 2022-3-12 12:41

本帖最后由 5i365 于 2022-3-12 12:43 编辑

下面的代码能取到顶级的值, 但是一到递归就蒙圈子   求高手接力
  1. $x = @'
  2. <?xml version="1.0" encoding="UTF-8"?>
  3. <opml version="1.0"
  4.     xmlns:sx="http://www.microsoft.com/schemas/rss/sse">
  5.     <head>
  6.         <title>顶级</title>
  7.     </head>
  8.     <body>
  9.         <outline text="一级1">
  10.             <outline text="二级1">
  11.                 <outline text="三级1">
  12.                     <outline text="四级1"></outline>
  13.                     <outline text="四级2"></outline>
  14.                 </outline>
  15.                 <outline text="三级2">
  16.                     <outline text="四级1"></outline>
  17.                     <outline text="四级2"></outline>
  18.                 </outline>
  19.             </outline>
  20.             <outline text="二级2">
  21.                 <outline text="三级1">
  22.                     <outline text="四级1"></outline>
  23.                     <outline text="四级2"></outline>
  24.                 </outline>
  25.                 <outline text="三级2">
  26.                     <outline text="四级1"></outline>
  27.                     <outline text="四级2"></outline>
  28.                 </outline>
  29.             </outline>
  30.         </outline>
  31.         <outline text="一级2">
  32.             <outline text="二级1">
  33.                 <outline text="三级1">
  34.                     <outline text="四级1"></outline>
  35.                     <outline text="四级2"></outline>
  36.                 </outline>
  37.                 <outline text="三级2">
  38.                     <outline text="四级1"></outline>
  39.                     <outline text="四级2"></outline>
  40.                 </outline>
  41.             </outline>
  42.             <outline text="二级2">
  43.                 <outline text="三级1">
  44.                     <outline text="四级1"></outline>
  45.                     <outline text="四级2"></outline>
  46.                 </outline>
  47.                 <outline text="三级2">
  48.                     <outline text="四级1"></outline>
  49.                     <outline text="四级2"></outline>
  50.                 </outline>
  51.             </outline>
  52.         </outline>
  53.         <outline text="一级3">
  54.             <outline text="二级1">
  55.                 <outline text="三级1">
  56.                     <outline text="四级1"></outline>
  57.                     <outline text="四级2"></outline>
  58.                 </outline>
  59.                 <outline text="三级2">
  60.                     <outline text="四级1"></outline>
  61.                     <outline text="四级2"></outline>
  62.                 </outline>
  63.             </outline>
  64.             <outline text="二级2">
  65.                 <outline text="三级1">
  66.                     <outline text="四级1"></outline>
  67.                     <outline text="四级2"></outline>
  68.                 </outline>
  69.                 <outline text="三级2">
  70.                     <outline text="四级1"></outline>
  71.                     <outline text="四级2"></outline>
  72.                 </outline>
  73.             </outline>
  74.         </outline>
  75.     </body>
  76. </opml>
  77. '@
  78. $xmldata = [xml]$x
  79. $xmldata.SelectNodes("opml/head/title")
复制代码

作者: idwma    时间: 2022-3-12 14:35

递归学会了来试试
  1. $a=$xmldata.SelectNodes("opml/body").item(0)
  2. function md4xml(){
  3. $args[0].ChildNodes|%{
  4.   $p+='\'+$_.text
  5.   mkdir ".$p"
  6.   md4xml $_
  7.   rv p
  8. }
  9. }
  10. md4xml $a
复制代码

作者: 5i365    时间: 2022-3-12 16:07

本帖最后由 5i365 于 2022-3-12 16:09 编辑

回复 3# idwma


感谢大侠支招, 真是看不懂了, 怎么函数md4xml里面还有md4xml函数

代码执行后,没有建顶级文件夹,下面这个$top应该加在哪里?
$top=$xmldata.SelectNodes("opml/head/title")

另外, 执行之后, 我再次执行会扫码报错, 能实现已经有的文件夹,就不要创建了, 只新建没有的吗
作者: idwma    时间: 2022-3-12 16:28

回复 4# 5i365

也不知道为什么要函数里套函数
  1. function md4xml(){
  2. $args[0].ChildNodes|%{
  3. if($_.title -eq $null){
  4.   $p+='\'+$_.text
  5.   if(!(test-path ".$pp$p")){mkdir ".$pp$p"}
  6.   md4xml $_
  7.   rv p
  8. }else{
  9. $pp='\'+$_.title
  10. if(!(test-path ".$pp")){mkdir ".$pp"}
  11. }
  12. }
  13. }
  14. md4xml $xmldata.ChildNodes.Item(1)
复制代码

作者: went    时间: 2022-3-12 23:22

简单的递归原理, 1+...+100
递归必须要有递归出口,不然会造成死循环
  1. function fn($num){
  2.     if($num -eq 1){
  3.         Write-Host '递归出口'
  4.         return 1
  5.     }
  6.     Write-Host "${num}压栈"
  7.     $sum = fn -num ($num-1)
  8.     Write-Host "${num}出栈"
  9.     return $num + $sum
  10. }
  11. fn(100)
复制代码

作者: 5i365    时间: 2022-3-13 06:20

本帖最后由 5i365 于 2022-3-13 06:22 编辑

回复 6# went


非常感谢went大侠赐教, 还是似懂非懂, 先mark收藏,

foreach遍历前些日子刚理解了, 现在又出一个递归拦路虎

感觉在实现某些功能上, PS的代码量要比其它的脚本语言少多了, 而且越少的PS代码越难理解
作者: 5i365    时间: 2022-3-13 08:42

本帖最后由 5i365 于 2022-3-13 08:45 编辑

回复 5# idwma


  大侠好, 能否再给代码加点 AI智能 吗? 描述如下:

在根据xml创建文件夹时,先遍历搜索 顶级文件夹下有没有同名的文件夹:

A.有一个的话, 就不新建了, 把存在的文件夹移过来

B.没有的话,再新建

C.有多个的话,就回显这N个文件夹的路径,每个路径前有序号,询问移哪个文件夹,输入序号回车,就移过去了

最好能把移动的中间路径过程定向输出到log.txt, 怕到时候找不到了

这次感觉有点难度了, 估计把上面的每个功能定义为一个函数, 然后在上面的代码中, 函数里面套多个函数了

作者: idwma    时间: 2022-3-13 17:29

回复 8# 5i365


    移过来移过去,往哪移?
作者: 5i365    时间: 2022-3-13 17:40

回复 9# idwma

比如, 按XML中的节点, 顶级下需要创建一个 一级1 的文件夹, 但是这个文件夹,已经在顶级的一个子文件夹中存在了, 就把它移过来
作者: 5i365    时间: 2022-3-13 18:08

回复 9# idwma


    这个对应的实际使用情况是, 已经执行过代码一次了, 但是我后来又修改或移动了XML中某个节点了, 再次执行代码, 实际上, 要建的文件夹已经存在了, 所以就不能新建它了, 要找到它, 移到要新建的地方
作者: idwma    时间: 2022-3-13 18:39

本帖最后由 idwma 于 2022-3-13 20:23 编辑

回复 11# 5i365
  1. function md4xml(){
  2. $args[0].ChildNodes|%{
  3. if($_.title -eq $null){
  4.   $p+='\'+$_.text
  5.   if(!(test-path ".$pp$p")){
  6. $a=dir -rec -inc $p.Split('\')[-1] ".$pp"
  7. if($a.count -gt 1){
  8. $a|%{"{0} {1}" -f $j++,$_.fullname}
  9. "-> .$pp$p"
  10. [int]$i=read-host
  11. if($i -match '\d'){move $a[$i].fullname ".$pp$p\.."; ac log.txt $("{0} -> {1}" -f $a[$i].fullname,".$pp$p")}
  12. rv i,j
  13. }elseif($a -ne $null){move $a.fullname ".$pp$p\.."; ac log.txt $("{0} -> {1}" -f $a.fullname,".$pp$p")}else{mkdir ".$pp$p"}
  14. }
  15.   md4xml $_
  16.   rv p
  17. }else{
  18. $pp='\'+$_.title
  19. if(!(test-path ".$pp")){mkdir ".$pp"}
  20. }
  21. }
  22. }
  23. md4xml $xmldata.ChildNodes.Item(1)
复制代码

作者: 5i365    时间: 2022-3-13 19:41

本帖最后由 5i365 于 2022-3-13 19:43 编辑

回复 12# idwma


感谢大侠支招, 还没有测试, 过两天再试, 因为我用的notepad2不管怎么试都会存成UTF8的乱码, 别的代码就没事, 估计是XML的内容+bat格式出错了, 已经反馈开发者了

系统已经改注册表, 替换了系统自带的记事本了, 暂时不想使用其它的软件, 用powershell studio 天生对中文支持就不好, 也经常乱码


作者: 5i365    时间: 2022-3-14 08:32

本帖最后由 5i365 于 2022-3-14 08:33 编辑

回复 12# idwma


   notepad2开发者回复了, 问题临时解决了, 我执行代码后,对于一级文件夹, 只创建了一个一级1, 没有其它两个, 下面是完整代码
  1. #@&cls&powershell "gc '%~0'|out-string|iex"&pause&exit
  2. $x = @'
  3. <?xml version="1.0" encoding="UTF-8"?>
  4. <opml version="1.0"
  5.     xmlns:sx="http://www.microsoft.com/schemas/rss/sse">
  6.     <head>
  7.         <title>顶级</title>
  8.     </head>
  9.     <body>
  10.         <outline text="一级1">
  11.             <outline text="二级1">
  12.                 <outline text="三级1">
  13.                     <outline text="四级1"></outline>
  14.                     <outline text="四级2"></outline>
  15.                 </outline>
  16.                 <outline text="三级2">
  17.                     <outline text="四级1"></outline>
  18.                     <outline text="四级2"></outline>
  19.                 </outline>
  20.             </outline>
  21.             <outline text="二级2">
  22.                 <outline text="三级1">
  23.                     <outline text="四级1"></outline>
  24.                     <outline text="四级2"></outline>
  25.                 </outline>
  26.                 <outline text="三级2">
  27.                     <outline text="四级1"></outline>
  28.                     <outline text="四级2"></outline>
  29.                 </outline>
  30.             </outline>
  31.         </outline>
  32.         <outline text="一级2">
  33.             <outline text="二级1">
  34.                 <outline text="三级1">
  35.                     <outline text="四级1"></outline>
  36.                     <outline text="四级2"></outline>
  37.                 </outline>
  38.                 <outline text="三级2">
  39.                     <outline text="四级1"></outline>
  40.                     <outline text="四级2"></outline>
  41.                 </outline>
  42.             </outline>
  43.             <outline text="二级2">
  44.                 <outline text="三级1">
  45.                     <outline text="四级1"></outline>
  46.                     <outline text="四级2"></outline>
  47.                 </outline>
  48.                 <outline text="三级2">
  49.                     <outline text="四级1"></outline>
  50.                     <outline text="四级2"></outline>
  51.                 </outline>
  52.             </outline>
  53.         </outline>
  54.         <outline text="一级3">
  55.             <outline text="二级1">
  56.                 <outline text="三级1">
  57.                     <outline text="四级1"></outline>
  58.                     <outline text="四级2"></outline>
  59.                 </outline>
  60.                 <outline text="三级2">
  61.                     <outline text="四级1"></outline>
  62.                     <outline text="四级2"></outline>
  63.                 </outline>
  64.             </outline>
  65.             <outline text="二级2">
  66.                 <outline text="三级1">
  67.                     <outline text="四级1"></outline>
  68.                     <outline text="四级2"></outline>
  69.                 </outline>
  70.                 <outline text="三级2">
  71.                     <outline text="四级1"></outline>
  72.                     <outline text="四级2"></outline>
  73.                 </outline>
  74.             </outline>
  75.         </outline>
  76.     </body>
  77. </opml>
  78. '@
  79. $xmldata = [xml]$x
  80. function md4xml()
  81. {
  82. $args[0].ChildNodes | %{
  83. if ($_.title -eq $null)
  84. {
  85. $p += '\' + $_.text
  86. if (!(test-path ".$pp$p"))
  87. {
  88. mkdir ".$pp$p"
  89. $a = dir -rec -inc $p.Split('\')[-1] ".$pp"
  90. if ($a.count -gt 1)
  91. {
  92. $a | %{ "{0} {1}" -f $j++ ,$_.fullname }
  93. "-> .$pp$p"
  94. [int]$i = read-host
  95. if ($i -match '\d') { move $($a[$i].fullname + '\*') ".$pp$p"; if ($?) { del $a[$i].fullname }; ac log.txt $("{0} -> {1}" -f $($a[$i].fullname + '\*'), $(".$pp$p")) }
  96. rv i, j
  97. }
  98. elseif ($a -ne $null) { move $($a.fullname + '\*') ".$pp$p"; if ($?) { del $a.fullname }; ac log.txt $("{0} -> {1}" -f $($a.fullname + '\*'), $(".$pp$p")) }
  99. }
  100. md4xml $_
  101. rv p
  102. }
  103. else
  104. {
  105. $pp = '\' + $_.title
  106. if (!(test-path ".$pp")) { mkdir ".$pp" }
  107. }
  108. }
  109. }
  110. md4xml $xmldata.ChildNodes.Item(1)
复制代码

作者: idwma    时间: 2022-3-14 13:31

回复 14# 5i365


    这里面子文件名不都是一样的吗?一样不就只保留一个了吗?
作者: 5i365    时间: 2022-3-14 13:52

回复 15# idwma

感谢大侠提醒, 这个逻辑和XML的结构在有同名文件夹时冲突了, 我再想想怎么描述, 确实有规律




欢迎光临 批处理之家 (http://www.bathome.net/) Powered by Discuz! 7.2