我有一个简单但很庞大的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完成它。
答案 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}