将 xmlstarlet 用于 select 不包含特定子节点的节点
Use xmlstarlet to select nodes that do NOT contain a specific subnode
我有几千条类似下面的记录
<holding>
<holding_id>2225031160001858</holding_id>
<record>
<leader>00210cx a22200085 454500</leader>
<controlfield tag="001">h38165-01alliance_ohsu</controlfield>
<controlfield tag="004">b10145746-01alliance_ohsu</controlfield>
<controlfield tag="005">20200417125900.0</controlfield>
<controlfield tag="008">2004170u\\0\[=11=]01aaund0999999</controlfield>
<datafield ind1="2" ind2=" " tag="852">
<subfield code="b">OHSUMAIN</subfield>
<subfield code="c">oldstorjrl</subfield>
</datafield>
</record>
</holding>
我需要将 datafield
@ind1
更改为 " ",其中 @tag="852
" 并且不存在带有 @code="h"
的 subfield
。在此示例中,@code="b"
和@code="c"
存在,但是@code="h"
不存在,所以我想修改这条记录。
我可以想办法使用程序逻辑来完成我需要的东西,但是我可以根据没有子节点直接使用xmlstarlet来select我想要的节点吗?
此记录的期望输出为
<holding>
<holding_id>2225031160001858</holding_id>
<record>
<leader>00210cx a22200085 454500</leader>
<controlfield tag="001">h38165-01alliance_ohsu</controlfield>
<controlfield tag="004">b10145746-01alliance_ohsu</controlfield>
<controlfield tag="005">20200417125900.0</controlfield>
<controlfield tag="008">2004170u\\0\[=12=]01aaund0999999</controlfield>
<datafield ind1=" " ind2=" " tag="852">
<subfield code="b">OHSUMAIN</subfield>
<subfield code="c">oldstorjrl</subfield>
</datafield>
</record>
</holding>
此 xpath 表达式应该 select 正确的目标节点:
"//datafield[@ind1][not(subfield[@code="h"])]"
不知道我是怎么错过的,但结果很简单
xmlstarlet ed -u '/holding/record/datafield[@tag="852"][not(subfield[@code="h"])]/@ind1' -v ' '
我有几千条类似下面的记录
<holding>
<holding_id>2225031160001858</holding_id>
<record>
<leader>00210cx a22200085 454500</leader>
<controlfield tag="001">h38165-01alliance_ohsu</controlfield>
<controlfield tag="004">b10145746-01alliance_ohsu</controlfield>
<controlfield tag="005">20200417125900.0</controlfield>
<controlfield tag="008">2004170u\\0\[=11=]01aaund0999999</controlfield>
<datafield ind1="2" ind2=" " tag="852">
<subfield code="b">OHSUMAIN</subfield>
<subfield code="c">oldstorjrl</subfield>
</datafield>
</record>
</holding>
我需要将 datafield
@ind1
更改为 " ",其中 @tag="852
" 并且不存在带有 @code="h"
的 subfield
。在此示例中,@code="b"
和@code="c"
存在,但是@code="h"
不存在,所以我想修改这条记录。
我可以想办法使用程序逻辑来完成我需要的东西,但是我可以根据没有子节点直接使用xmlstarlet来select我想要的节点吗?
此记录的期望输出为
<holding>
<holding_id>2225031160001858</holding_id>
<record>
<leader>00210cx a22200085 454500</leader>
<controlfield tag="001">h38165-01alliance_ohsu</controlfield>
<controlfield tag="004">b10145746-01alliance_ohsu</controlfield>
<controlfield tag="005">20200417125900.0</controlfield>
<controlfield tag="008">2004170u\\0\[=12=]01aaund0999999</controlfield>
<datafield ind1=" " ind2=" " tag="852">
<subfield code="b">OHSUMAIN</subfield>
<subfield code="c">oldstorjrl</subfield>
</datafield>
</record>
</holding>
此 xpath 表达式应该 select 正确的目标节点:
"//datafield[@ind1][not(subfield[@code="h"])]"
不知道我是怎么错过的,但结果很简单
xmlstarlet ed -u '/holding/record/datafield[@tag="852"][not(subfield[@code="h"])]/@ind1' -v ' '