在 PHP 中过滤子标签上的 XML 并返回父标签
Posted
技术标签:
【中文标题】在 PHP 中过滤子标签上的 XML 并返回父标签【英文标题】:Filter XML on child tag in PHP and return parent tags 【发布时间】:2021-03-27 09:24:00 【问题描述】:正如标题所述,我有一个如下所示的 XML,其中一个帐户展开以查看内容。
<?xml version="1.0" encoding="utf-8"?>
<eExact
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="eExact-XML.xsd">
<Accounts>
<Account code="0" searchcode="" status="A" > </Account>
<Account code="1" searchcode="" status="A" > </Account>
<Account code="3" searchcode="" status="C" > </Account>
<Account code="4" searchcode="" status="C" > </Account>
<Account code="2" searchcode="" status="C" >
<Name>Company 1</Name>
<Phone>684564</Phone>
<Email>info@company1.com</Email>
<Contact number="2090075" gender="M" default="1" ID="2449ce5d-41b3-4f80-bab3-d13f6687dfe4">
<LastName>Doe</LastName>
<FirstName>Tom</FirstName>
<Phone>44546456456e</Phone>
<Email>tom.doe@company1.com</Email>
</Contact>
<Address type="SIV" default="1" ID="41bde841-afde-4f5d-9cd0-a12ecf6f6777">
<AddressLine1>adress</AddressLine1>
<PostalCode>10000</PostalCode>
<City>TheCity</City>
<Contact number="2090075" ID="2449ce5d-41b3-4f80-bab3-d13f6687dfe4" />
</Address>
<VATNumber>a_VAT_number_XXXX</VATNumber>
<VATLiability>L</VATLiability>
<SalesCurrency code="EUR" />
<PurchaseCurrency code="EUR" />
</Account>
</Accounts>
<Topics>
<Topic code="Accounts" ts_d="0x000000006517487D" count="5" pagesize="1000" />
</Topics>
<Messages />
</eExact>
我要做的是返回状态为 C 并在 VATNumber 标记中包含值的帐户。有些帐户不包含 VATNumber 中的值,所以我希望那些被过滤掉或不返回。
到目前为止,我设法退回了 C 帐户,但没有过滤增值税号。
$document = new DOMDocument();
$document->loadXML($response);
$xpath = new DOMxpath($document);
foreach ($xpath->evaluate('(/eExact/Accounts/Account[@status="C"])') as $account)
$json[] = [
'email' => $xpath->evaluate('string(Contact[@default="1"]/Email)', $account),
//'username' => $xpath->evaluate('string(Contact[@default="1"]/FirstName)', $account),
'first_name' => $xpath->evaluate('string(Contact[@default="1"]/FirstName)', $account),
'last_name' => $xpath->evaluate('string(Contact[@default="1"]/LastName)', $account),
'billing' => [
'first_name' => $xpath->evaluate('string(Contact[@default="1"]/FirstName)', $account),
'last_name' => $xpath->evaluate('string(Contact[@default="1"]/LastName)', $account),
'postcode'=> $xpath->evaluate('string(Address[@default="1"]/PostalCode)', $account),
'VATNumber' => $xpath->evaluate('string(VATNumber)', $account),
],
];
// ...
$customer = json_encode($json, JSON_PRETTY_PRINT);
$customers = "\"create\": $customer \t";
// echo $customer;
echo $customers;
它给了我这个输出:
Key OK"create": [
"email": "john.doe@company2.com",
"first_name": "John",
"last_name": "Doe",
"billing":
"first_name": "John",
"last_name": "Doe",
"postcode": "",
"VATNumber": ""
,
"email": "steve.known@company3.com",
"first_name": "Steve",
"last_name": "Known",
"billing":
"first_name": "Steve",
"last_name": "Known",
"postcode": "",
"VATNumber": ""
,
"email": "tom.doe@company1.com",
"first_name": "Tom",
"last_name": "Doe",
"billing":
"first_name": "Tom",
"last_name": "Doe",
"postcode": "9200",
"VATNumber": "a_VAT_number_XXXX"
我该如何做到这一点,以使 John 和 Steve 不会因为他们的增值税号为空而出现?
我假设在创建数组之前我需要先过滤。
【问题讨论】:
【参考方案1】:如果值为not empty
,您只需要一个 if 语句测试。
if (!empty($xpath->evaluate('string(VATNUMBER)', $account)))
$json[] = [
'email' => $xpath->evaluate('string(Contact[@default="1"]/Email)', $account),
//'username' => $xpath->evaluate('string(Contact[@default="1"]/FirstName)', $account),
'first_name' => $xpath->evaluate('string(Contact[@default="1"]/FirstName)', $account),
'last_name' => $xpath->evaluate('string(Contact[@default="1"]/LastName)', $account),
'billing' => [
'first_name' => $xpath->evaluate('string(Contact[@default="1"]/FirstName)', $account),
'last_name' => $xpath->evaluate('string(Contact[@default="1"]/LastName)', $account),
'postcode'=> $xpath->evaluate('string(Address[@default="1"]/PostalCode)', $account),
'VATNumber' => $xpath->evaluate('string(VATNumber)', $account),
],
];
// ...
只要我的 php 没有完全付诸东流,将 $json[] = [
封装在 If 语句中将测试该值是否为 empty
,如果是,则将其从结果中省略。
【讨论】:
【参考方案2】:您可以扩展您的初始 XPath 表达式以包括检查非空增值税号,以便它只处理这些元素...
/eExact/Accounts/Account[@status="C" and VATNumber/text()]
我还将初始化$json
,就好像没有记录一样,你会得到一个未定义的变量错误。所以...
$json = [];
foreach ( $xpath->query('/eExact/Accounts/Account[@status="C" and VATNumber/text()]') as $account)
【讨论】:
或/eExact/Accounts/Account[@status="C" and normalize-space(VATNumber) != ""]
以上是关于在 PHP 中过滤子标签上的 XML 并返回父标签的主要内容,如果未能解决你的问题,请参考以下文章
解析具有相同父子标签的 XML,然后最好使用 SAX 解析器将父标签的值链接到子标签
如何使父标签和子标签在b-form-checkbox上具有onclick而不重复
怎么用js代码复制父标签底下子标签以及样式,再将子标签加入到父标签中