示例 XML:
<outerTag>
<innerElement>
<Id>1234</Id>
<fName>Kim</fName>
<lName>Scott</lName>
<customData1>Value1</customData1>
<customData2>Value2</customData2>
<position>North<position>
<title/>
</innerElement>
<innerElement>
<Id>5678</Id>
<fName>Brian</fName>
<lName>Davis</lName>
<customData3>value3</customData3>
<customData4>value4</customData4>
<customData5>value5</customData5>
<position>South<position>
<title/>
</innerElement>
</outerTag>
预期产出:
<outerTag>
<innerElement>
<Id>1234</Id>
<fName>Kim</fName>
<lName>Scott</lName>
<customData1>Value1</customData1>
<customData2>Value2</customData2>
<position>North<position><title/></position>
</position>
</innerElement>
</outerTag>
我知道我可以只使用好的选择
Xpath
来做这个把戏,但我试图弄清楚如何使用delete
和xidel来正确
XQuery
。
我从this试过:
xidel --xml -e '
let $element := //innerElement[not(Id["1234"])]
declare function local:process-xml ($element) {
$element update delete node
}
' file.xml
我得到:
An unhandled exception occurred at $00000000006174CA:
ERangeError: Range check error
$00000000006174CA
$000000000061782C
$0000000000629536
$000000000062E638
$000000000055C12B
或
$ xidel --xquery '
let $element := //innerElement[./not(Id["1234"])]
declare function local:process-xml ($element) {
$element update delete node
}
' file.xml
我得到同样的错误。
或者使用 纯 XQuery:
$ xidel --xml --xquery '
let $input := /outerTag
modify delete node $input/innerElement[Id ne "1234"]
return $input
' file.xml
我得到错误:
Error:
err:XPST0003: Missing whitespace or symbol
in line 2 column 5
modify delete node $input/innerElement[Id ne "1234"]
^^^^ error occurs around here
令人沮丧
xidel
无法处理这种纯粹的XQuery
解决方案。
这里是一个纯 XQuery 解决方案,在 BaseX 10.5 中测试
XQuery
declare context item := document {
<outerTag>
<innerElement>
<Id>1234</Id>
<fName>Kim</fName>
<lName>Scott</lName>
<customData1>Value1</customData1>
<customData2>Value2</customData2>
<position>North</position>
<title/>
</innerElement>
<innerElement>
<Id>5678</Id>
<fName>Brian</fName>
<lName>Davis</lName>
<customData3>value3</customData3>
<customData4>value4</customData4>
<customData5>value5</customData5>
<position>South</position>
<title/>
</innerElement>
</outerTag>
};
copy $input := .
modify delete node $input/outerTag/innerElement[Id ne "1234"]
return $input
输出
<outerTag>
<innerElement>
<Id>1234</Id>
<fName>Kim</fName>
<lName>Scott</lName>
<customData1>Value1</customData1>
<customData2>Value2</customData2>
<position>North</position>
<title/>
</innerElement>
</outerTag>
XQuery #2
以文件名作为参数
declare base-uri 'e:\Temp\';
declare option db:stripws "true";
copy $input := doc("input.xml")
modify delete node $input/outerTag/innerElement[Id ne "1234"]
return $input
Linux 版本:
copy $input := doc("/tmp/file.xml")
modify delete node $input/outerTag/innerElement[Id ne "1234"]
return $input
Xidel 不支持“XQuery 更新”。参见邮件列表讨论。
附带说明:虽然可以使用 Xidel 编辑 XML,但它的目标不是成为一个完全成熟的编辑器。 Benito 创建 Xidel 的初衷是作为提取器。
你可以使用
transform()
,但是wiki已经很久没有更新了,目前这个功能已经被弃用了:
$ xidel -s file.xml -e '
transform(
/,
function($x){
if (name($x)="innerElement" and $x/Id="5678")
then ()
else $x
}
)
' --output-node-format=xml --output-node-indent
pxp:transform(..) is deprecated, use x:transform-nodes(..)
<outerTag>
<innerElement>
<Id>1234</Id>
<fName>Kim</fName>
<lName>Scott</lName>
<customData1>Value1</customData1>
<customData2>Value2</customData2>
<position>North</position>
<title/>
</innerElement>
</outerTag>
x:replace-nodes()
,它更容易使用:
$ xidel -s file.xml -e 'x:replace-nodes(//innerElement[Id="5678"],())' \
--output-node-format=xml --output-node-indent