[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]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>

  1. (type a.xml) -join '' -replace '\s+<direction.*>ABC<.*?/direction>','' -replace '>\s',">`r`n"
复制代码

TOP

回复 2# idwma


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

| out-file aaa.xml -Encoding default

TOP

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

TOP

回复 3# 5i365

不稳吗?正则挻通用的万金油
  1. $a=type a.xml
  2. $ofs="`n"
  3. "$a" -replace '\s*<direction[\s\S]*>ABC<[\s\S]*?/direction>',''
复制代码

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

回复 7# 5i365

不是这样写的。且这样没有通用性,你应该按"ABC"去查找,不宜写死节点名。查找InnerText="ABC"的节点或父节点或爷节点。
QQ: 己阵亡
脚本优先 [PowerShell win10]

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

本帖最后由 idwma 于 2021-12-26 15:03 编辑

回复 11# 5i365
  1. sc b.xml ([io.file]::ReadAllText("a.xml") -replace '\s*<direction.*>[\r\n\s]*<.*>ABC<[\s\S]*?/direction>','')
复制代码

TOP

本帖最后由 idwma 于 2021-12-26 17:48 编辑

回复 10# 5i365
  1. https://docs.microsoft.com/zh-cn/previous-versions/dotnet/netframework-4.0/ms256086(v=vs.100)
复制代码
  1. [xml]$a=type a.xml
  2. $b=$a.SelectSingleNode("//descendant::direction[direction-type/rehearsal='ABC']")
  3. $b.ParentNode.RemoveChild($b)
  4. $a.save("b.xml")
复制代码

TOP

回复 13# idwma


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

TOP

回复 13# idwma


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

TOP

返回列表