我需要过滤一个大文件 XML 并使用多个条件查找字符串。如果 cnisfCF 等于 true 并且 natg_passwordAlreadyResetedPostMigration 为 true,我需要过滤电子邮件。
任何人都可以帮忙吗?
<customer customer-no="09090909090">
<credentials>
<login>[email protected]</login>
<enabled-flag>true</enabled-flag>
<password-question/>
<password-answer/>
</credentials>
<profile>
<salutation/>
<title/>
<first-name>teste</first-name>
<second-name/>
<last-name>name 1</last-name>
<suffix/>
<company-name/>
<job-title/>
<email>[email protected]</email>
<phone-home>542926407485</phone-home>
<phone-business/>
<phone-mobile/>
<fax/>
<birthday>1999-09-12Z</birthday>
<gender>2</gender>
<creation-date>2022-09-19T18:34:45.000Z</creation-date>
<preferred-locale/>
<custom-attributes>
<custom-attribute attribute-id="natg_Newsletter">false</custom-attribute>
<custom-attribute attribute-id="natg_cfIsCn">false</custom-attribute>
<custom-attribute attribute-id="natg_cpf">5465465456456</custom-attribute>
<custom-attribute attribute-id="natg_infContOptIn">false</custom-attribute>
<custom-attribute attribute-id="natg_optInWP">false</custom-attribute>
<custom-attribute attribute-id="natg_passwordAlreadyResetedPostMigration">true</custom-attribute>
<custom-attribute attribute-id="natg_personNumber">116864397</custom-attribute>
<custom-attribute attribute-id="natg_pushOptIn">false</custom-attribute>
<custom-attribute attribute-id="natg_rut">456456456</custom-attribute>
</custom-attributes>
</profile>
答案1
在测试运行以下命令之前,我冒昧地</customer>
在数据中添加了缺少的结束标记,并假设您是cnisfCF
这样的natg_cfIsCn
(属性和节点名称区分大小写)。
使用xmlastarlet
:
xmlstarlet select --template \
--match '//profile' \
--match 'self::node()[custom-attributes/custom-attribute[@attribute-id="natg_cfIsCn"]="true"]' \
--match 'self::node()[custom-attributes/custom-attribute[@attribute-id="natg_passwordAlreadyResetedPostMigration"]="true"]' \
--value-of 'email' -nl file.xml
上述命令将提取输入文档中email
任何具有属性和以及值和的子节点的节点中的节点值。profile
custom-attributes/custom-attribute
attribute-id
natg_cfIsCn
natg_passwordAlreadyResetedPostMigration
false
true
这里棘手的事情是以可读的方式呈现命令,因为路径中涉及的节点名称太长。我通过首先匹配//profile
路径,然后执行两个单独的步骤来缩小结果集的范围来解决这个问题。
仅使用单个“value-of”XPath 查询的 select 语句如下所示
xmlstarlet select --template \
--value-of '//profile[
custom-attributes/custom-attribute[@attribute-id="natg_cfIsCn"]="true" and
custom-attributes/custom-attribute[@attribute-id="natg_passwordAlreadyResetedPostMigration"]="true"
]/email' -nl file.xml
如果这看起来更漂亮,那就用它来代替。我相信它们应该是等价的。
请注意,上述命令不会为给定文档生成任何输出,因为没有与查询匹配的数据。