希望有人能在这里为我的XPath查询提供建议。我想提取并显示字符串的一部分,但目前得到的结果是返回完整的字符串。我希望能够得到两个像下面这样的结果。
<airline>
<flight-number flight_id="flt-888712-departure-date-arrival-arrival-date-0101">01</flight-number>
<flight-number flight_id="flt-888712-departure-date-arrival-arrival-date-0102">02</flight-number>
</airline>
这是我正在使用的xml文件flights.xml。
<airline>
<flight-number flight_id="flt-888712-departure-date-arrival-date-0102">01–02</flight-number>
</airline>
例如,当我尝试下面的XPath查询时,我只得到了01-02,但要得到上面所说的,还需要做更多的工作。我希望01和02的字符串分别返回。/airline/flight-number/child::text()
有人能建议我如何使用XPath来实现我正在尝试做的事情的结果吗?
我希望能够使用xmlstarlet获得两个结果,比如下面的结果:# shellcheck shell=sh disable=SC2016 xmlstarlet edit --omit-decl --var fn '//flight-number[@flight_id="flt-888712-departure-date-arrival-date-0102"]' -a '$fn' -t elem -n 'flight-number' -u '$prev' -x '$fn/node() | $fn/@*' -u '$prev/text()' -x 'substring-after(.,"–")' -u '$fn/text()' -x 'substring-before(.,"–")' file.xml
--var
将相关节点保存在名为fn
的变量中-a …
附加一个空的同名同级节点$prev
(也称为$xstar:prev
(变量指的是创建的节点由最近的-i (--insert)
、-a (--append)
或-s (--subnode)
选项中给出了$prev
的示例doc/xmlstarlet.txt- 第一个
-u …
使新的同级成为$fn
的副本,复制其子节点和属性节点- 第2个
-u …
更新新同级节点的文本- 第3个
-u …
更新原始节点的文本- XPath 1.0字符串函数有文档记录在这里CCD_ 15的用户指南是这里
输出:
<airline> <flight-number flight_id="flt-888712-departure-date-arrival-date-0102">01</flight-number> <flight-number flight_id="flt-888712-departure-date-arrival-date-0102">02</flight-number> </airline>
更新2022-09-25
如果输入包含一系列航班,则每个航班都可以获得一个同级节点像这样,
xmlstarlet edit --omit-decl --var fln '//flight-number' -a '$fln' -t elem -n 'flight-number' --var sib '$fln/following-sibling::*[position() mod 2 = 1]' -u '$sib' -x 'preceding-sibling::*[1]/node() | preceding-sibling::*[1]/@*' -u '$fln/text()' -x 'substring-before(.,"-")' -u '$sib/text()' -x 'substring-after(.,"-")' file.xml
其中变量CCD_ 16引用交错的兄弟。
样本输出:
<airline> <flight-number flight_id="flt-888712-0102">01</flight-number> <flight-number flight_id="flt-888712-0102">02</flight-number> <flight-number flight_id="flt-123456-0910">09</flight-number> <flight-number flight_id="flt-123456-0910">10</flight-number> <flight-number flight_id="flt-789012-3031">30</flight-number> <flight-number flight_id="flt-789012-3031">31</flight-number> </airline>
(结束更新(
使用xmlstarlet
和bash
:
alias xml=xmlstarlet
f1=$( xml sel -t -m 'airline/flight-number' -v 'substring-before(., "-")' infile.xml)
f2=$( xml sel -t -m 'airline/flight-number' -v 'substring-after (., "-")' infile.xml)
fid=$(xml sel -t -m 'airline/flight-number/@flight_id'
-v 'substring(., 1, string-length(.)-2)' infile.xml)
xml ed -d airline/flight-number infile.xml |
xml ed -s airline -type elem -n flight-number -v $f1 |
xml ed -s airline -type elem -n flight-number -v $f2 |
xml ed -a 'airline/flight-number[1]' -t attr -n flight_id -v $fid$f1 |
xml ed -a 'airline/flight-number[2]' -t attr -n flight_id -v $fid$f2
输出:
<?xml version="1.0"?>
<airline>
<flight-number flight_id="flt-888712-departure-date-arrival-date-0101">01</flight-number>
<flight-number flight_id="flt-888712-departure-date-arrival-date-0102">02</flight-number>
</airline>