是否有可能根据特定的XML属性提取所有Xml值: 例如,我需要使用所有具有相同auth_username的手机(第一个和最后一个手机具有相同的auth_username
<Fund>
<mobile>
<auth_username>736994</auth_username>
<client_name>736994_iPad</client_name>
<first_name>Yamelin</first_name>
<last_name>test</last_name>
</mobile>
<mobile>
<auth_username>735139</auth_username>
<client_name>735139_iPad</client_name>
<first_name>Eunbi</first_name>
<last_name>Eunbi</last_name>
</mobile>
<mobile>
<auth_username>733279</auth_username>
<client_name>733279_iPad</client_name>
<first_name>wang</first_name>
<last_name>test</last_name>
</mobile>
<mobile>
<auth_username>737618</auth_username>
<client_name>737618_iPad</client_name>
<first_name>test</first_name>
<last_name>testLast</last_name>
</mobile>
<mobile>
<auth_username>736994</auth_username>
<client_name>734131_iPad</client_name>
<first_name>Kai</first_name>
<last_name>test</last_name>
</mobile>
</Fund>
所需的输出必须类似于:
<Fund>
<mobile>
<auth_username>736994</auth_username>
<client_name>736994_iPad</client_name>
<first_name>Yamelin</first_name>
<last_name>test</last_name>
</mobile>
<mobile>
<auth_username>736994</auth_username>
<client_name>734131_iPad</client_name>
<first_name>Kai</first_name>
<last_name>test</last_name>
</mobile>
</Fund>
我尝试了xmlstarlet,但是我只将auth_username作为输出
DataFund = $(xmlstarlet sel -T -t -m“ Fund / mobile” -n -v“ auth_username”〜/ Desktop / DeviceAndUserFund2.csv | sort | uniq -d)
这是另一种方式吗?
答案 0 :(得分:1)
Bash功能本身并不十分适合您的XML要求类型。但是,这里有两个都使用XSLT stylesheet的解决方案。
首先保存以下.xsl
。我们将文件命名为get-dupes.xsl
get-dupes.xsl
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="no" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="duplicates" match="mobile" use="auth_username"/>
<xsl:template match="/Fund">
<xsl:element name="{name(/*)}">
<xsl:copy-of select="mobile[count(key('duplicates', auth_username)) > 1]"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
然后通过您的CLI运行以下 xmlstarlet 命令:
xml tr /path/to/get-dupes.xsl /path/to/input.xml
请注意,上面命令中的/path/to/
部分应更改为实际文件的真实路径。
生成的xml将包含所有具有相同<mobile>..</mobile>
值的<auth_username>
元素。
更多说明:
如果要省略xml声明(即<?xml version="1.0"?>
,则可以在命令中添加--omit-decl
选项。例如:
xml tr --omit-decl /path/to/get-dupes.xsl /path/to/input.xml
如果需要,您的源xml数据也可以通过管道传递到xml tr
命令。例如:
cat /path/to/input.xml | xml tr /path/to/get-dupes.xsl
要将结果XML分配给名为DataFund
的变量,可以执行以下操作:
DataFund="$(xml tr /path/to/get-dupes.xsl /path/to/input.xml)"
要将结果XML保存到新文件,可以按照以下示例使用重定向(>
):
xml tr /path/to/get-dupes.xsl /path/to/input.xml > path/to/output.xml
有关xml tr
命令和可用选项的更多信息,请参见here。
xml tr
命令的一般用法是:
xml tr [<options>] <xsl-file> {-p|-s <name>=<value>} [ <xml-file-or-uri> ... ]
您还可以使用xsltproc(已预先安装在macOS上)实现这一目标。
使用名为get_dupes.xsl
的XSLT样式表(如上所示),您可以:
通过运行以下命令从文件读取源XML:
xsltproc /path/to/get-dupes.xsl /path/to/input.xml
或者,将源XML传递给xsltproc
。例如:
cat input.xml | xsltproc /path/to/get-dupes.xsl -
请注意,以上使用了连字符(-
)从标准输入中读取源xml数据。
或者,将结果XML分配给名为DataFund
的变量,您可以执行以下操作:
DataFund="$(xsltproc /path/to/get-dupes.xsl /path/to/input.xml)"
xsltproc 没有可省略xml声明的选项。为此,您需要将 get-dupes.xsl 中的omit-xml-declaration="no"
属性更改为omit-xml-declaration="yes"