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

[问题求助] PowerShell在xml文件中根据某标签属性值删除其所在的父结点

在下面的xml文件中, 我想把rehearsal标签的属性值是ABC所在的父父结点删除, 在论坛和百度没找到确切的答案, 求请高手指点, 非常感谢


如下图所示, 即删除粉红色内的内容



---------------------------------------------------------------------------------------------------------------------
<?xml version="1.0" encoding="UTF-8"?>
<score-partwise version="3.1">
  <part id="P1">
    <measure number="1" width="118.81">
      <direction placement="above">
        <direction-type>
          <rehearsal default-x="-20.55" relative-y="30.00" font-weight="bold" font-size="14">ABC</rehearsal>
          </direction-type>
        </direction>
      <direction placement="above">
        <direction-type>
          <rehearsal default-x="-40.55" relative-y="60.00" font-weight="bold" font-size="14">CDE</rehearsal>
          </direction-type>
        </direction>
      </measure>
    </part>
  </score-partwise>

回复 2# idwma


    感谢大侠帮忙, 能实现删除效果,
我在代码后面加了下面代码, 生成了新的xml文件,
但有一个问题, 原来的第二行跑到第一行后面了,
具体的实例还没有尝试, 但总感觉用正则删,可能会有些不稳,

| out-file aaa.xml -Encoding default

TOP

找到一篇文章, 但是水平有限, 看不太懂
https://cloud.tencent.com/developer/ask/138618

TOP

回复 5# idwma


    用notepad2打开输出后的xml, 有下面的提示

TOP

本帖最后由 5i365 于 2021-12-25 12:50 编辑

回复 5# idwma


按上面链接的代码, 照葫芦画了两个瓢, 但是还是不能删除, 但是$nod可以取到值:
  1. [xml]$xml = Get-Content '.\xml.xml'
  2. $nod = $xml.SelectSingleNode("//rehearsal[contains(text(), 'ABC')]")
  3. $nod
  4. [void]$xml.score-partwise.part.measure.RemoveChild($nod.ParentNode)
  5. $xml.Save('.\ok.xml')
复制代码
------------------------------------------------
  1. $rom, $inp = '.\list.txt', '.\xml.xml'
  2. ($lst, $xml = (Get-Content $rom), [xml](Get-Content $inp))[0].ForEach{
  3. $nod = $xml.SelectSingleNode("//rehearsal[contains(text(), '$_')]")
  4. [void]$xml.score-partwise.part.measure.RemoveChild($nod.ParentNode)
  5. }
  6. $xml.Save('.\ok.xml')
复制代码

TOP

回复 8# xczxczxcz


    感谢提醒, 但是水平真是有限, 只懂一二, 卡关键点上了
上面链接的例子, 是删父结点, 我的是删爷结点

TOP

回复 5# idwma


    找到一段代码, 能理解, 但是不会运用
  1. $test = "<task>
  2.    <list>list1</list>
  3.    <list>list2</list>
  4.    <list>list3</list>
  5.    <list>list4</list>
  6.    <list>list5</list>
  7. </task>"
  8. [xml]$myxml = $test
  9. $remove = $myxml.task.SelectSingleNode("//list[.='list2']")
  10. $remove.ParentNode.RemoveChild($remove)
复制代码

TOP

回复 5# idwma


    试了一个长的xml文件, <text>标签内的中文都成乱码了, 加编码参数也不行
https://wss1.cn/f/77e4p6wnaq6 复制链接到浏览器打开

TOP

回复 13# idwma


    非常感谢!
但是表达式中的限定条件太多了, 而且有时并不知道那些条件, 只知道某个结点的值是ABC, 感觉应该还有更简单的办法

TOP

回复 13# idwma


刚刚试了上面两楼的代码,
12楼仍然是有乱码
13楼直接报错

TOP

回复 12# idwma


    用下面的代码, 可以删除自身所在的结点, 但是没有删除父结点和爷结点
  1. $test = @'
  2. <?xml version="1.0" encoding="UTF-8"?>
  3. <score-partwise version="3.1">
  4.   <part id="P1">
  5.     <measure number="1" width="118.81">
  6.       <direction placement="above">
  7.         <direction-type>
  8.           <rehearsal default-x="-20.55" relative-y="30.00" font-weight="bold" font-size="14">ABC</rehearsal>
  9.           </direction-type>
  10.         </direction>
  11.       <direction placement="above">
  12.         <direction-type>
  13.           <rehearsal default-x="-40.55" relative-y="60.00" font-weight="bold" font-size="14">CDE</rehearsal>
  14.           </direction-type>
  15.         </direction>
  16.       </measure>
  17.     </part>
  18.   </score-partwise>
  19. '@
  20. [xml]$a = $test
  21. $b = $a.SelectSingleNode("//rehearsal[contains(text(), 'ABC')]")
  22. $b.ParentNode.RemoveChild($b)
  23. $a.save("b.xml")
复制代码

TOP

回复 16# idwma


    对正则真是怕了, 如果看不懂, 一点也不会改, 若有特殊字符在多行里面, 真是担心不稳

TOP

回复 16# idwma


    我的那个网盘的 示例文件 蓝莲花.musicx  后缀虽不同, 但实际是xml文件, 用您的代码[xml]方式加载时, 直接会报错, 好像是提示xml结点有错误, 但是我用前面的代码就不会, 不知道为什么

TOP

本帖最后由 5i365 于 2021-12-26 21:15 编辑

回复 16# idwma


    发现曙光了, 用下面的代码能识别所在标签了, 这样只需要输入 ABC 字符就可以定位了
但是怎样删除爷结点呢?

$b=$a.SelectSingleNode("//*[contains(text(), 'ABC')]")

TOP

回复 20# idwma


    没有删除爷结点, 只删除了所在的标签, 因为它外面还有两层要删除

TOP

返回列表