XML子树 - 仅选择指定的子节点,但与父节点一起选择

时间:2014-08-20 17:45:14

标签: xml powershell xpath xquery

我有一个简单但很庞大的XML文件,它包含许多<file>个节点,我只想从中选择2个子节点<filename><bytes>(每个{{1} }})。我需要一个可以返回&#34;简化&#34;的集合的查询。仅由我的2个选定子节点组成的节点,如下所示:

<file>

但如果我使用以下查询:<file> <filename> <bytes> </file> <file> <filename> <bytes> </file> ,我将无法获得2个//file/*[self::filename or self::bytes]个节点,但有4个子节点:

<file>

我在PowerShell中的XML文件和演示:

<filename>
<bytes>
<filename>
<bytes>

有什么想法吗?

PS 我知道我可以通过其他各种方式实现这一目标,但我特别希望用xquery完成它。

2 个答案:

答案 0 :(得分:3)

您可以尝试删除XPath选择的节点:

cls; 
[xml]$xml = 
@"
<root>
    <file>
      <filename>file1.txt</filename>
      <md5>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA</md5>
      <bytes>69762</bytes>
      <executable>0</executable>
      <someothertag>x</someothertag>
    </file>
    <file>
      <filename>file2.txt</filename>
      <md5>BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB</md5>
      <bytes>78179</bytes>
      <executable>0</executable>
      <someothertag>y</someothertag>
    </file>
</root>
"@
#$xml

$dumy = $xml | Select-Xml -XPath '//file/*[self::md5 or self::executable or self::someothertag]' | Foreach {$_.Node.ParentNode.RemoveChild($_.Node)}
$xml.Save("c:\temp\test.xml")

然后修改c:\temp\test.xml以查看结果。

答案 1 :(得分:2)

一个简单的XPath表达式是不够的,因为这不能过滤子树。您需要构造新的结果元素。此XQuery表达式创建新的<file/>元素,并包括所有<filename/><bytes/>个子元素:

for $file in //file
return element file {filename, bytes}

如果您能够使用XQuery 3.0,则可以使用简单地图运算符来表达更短的语法:

//file ! element file {filename, bytes}