使用 PHP/cURL/JSON 将 XML 数据推送到 REST API
Push XML DATA to REST API with PHP/cURL/JSON
我遇到了一个问题。我正在尝试编写一个应用程序,它基本上从包含客户的在线 XML 文件中读取和排序数据,并在 Wordpress/woocommerce 到 cURL/php/JSON 中重新创建这些客户。我正在使用 insomnia 来测试我的调用和代码片段。
这是我目前得到的:
- 将客户数据从在线数据库中提取到 xml[但其原始未分类且信息过多]
- 通过 JSON/PHP/cURL
中的 POST 请求在 Woocommerce/Wordpress 中创建客户
我目前缺少将 XML 数据分类为 table 和将该数据填充到一段代码中的桥梁,该代码包含通过 REST [=58] 将所述数据重新创建到 woocommerce 中的变量=].
简而言之,我想:
将客户数据拉入 XML - OK
读取XML客户数据并将其赋值给变量
使用上述变量在 Woocommerce/wordpress 中推送和重新创建客户。
我该如何处理?
这就是我在 woocommerce 中创建客户的方式。基本上 CURL_POSTFIELDS
标签应该包含来自该客户 XML table 的一行及其分配数据。
<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://www.testsite.com/wp-json/wc/v3/customers?consumer_key=XXXXXXXXXXXX&consumer_secret=XXXXXXXXXXXXXXXXX",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => "{\n \"email\": \"john.doe@example.com\",\n \"first_name\": \"John\",\n \"last_name\": \"Doe\",\n \"username\": \"john.doe\",\n \"billing\": {\n \"first_name\": \"John\",\n \"last_name\": \"Doe\",\n \"company\": \"\",\n \"address_1\": \"969 Market\",\n \"address_2\": \"\",\n \"city\": \"San Francisco\",\n \"state\": \"CA\",\n \"postcode\": \"94103\",\n \"country\": \"US\",\n \"email\": \"john.doe@example.com\",\n \"phone\": \"(555) 555-5555\"\n },\n \"shipping\": {\n \"first_name\": \"John\",\n \"last_name\": \"Doe\",\n \"company\": \"\",\n \"address_1\": \"969 Market\",\n \"address_2\": \"\",\n \"city\": \"San Francisco\",\n \"state\": \"CA\",\n \"postcode\": \"94103\",\n \"country\": \"US\"\n }\n}",
CURLOPT_HTTPHEADER => [
"Authorization: Basic Og==",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
insomania 中的 JSON 有这些作为输入,与上面相同的故事,它应该用 XML:
中的客户数据填充
{
"email": "john.doe@example.com",
"first_name": "John",
"last_name": "Doe",
"username": "john.doe",
"billing": {
"first_name": "John",
"last_name": "Doe",
"company": "",
"address_1": "969 Market",
"address_2": "",
"city": "San Francisco",
"state": "CA",
"postcode": "94103",
"country": "US",
"email": "john.doe@example.com",
"phone": "(555) 555-5555"
},
"shipping": {
"first_name": "John",
"last_name": "Doe",
"company": "",
"address_1": "969 Market",
"address_2": "",
"city": "San Francisco",
"state": "CA",
"postcode": "94103",
"country": "US"
}
}
这是 XML 数据的响应示例。我已展开帐户代码 2 以显示其内容。显然我不想要它的所有内容,我只对姓名、电子邮件、地址、phone 和增值税号感兴趣。
<eExact
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="eExact-XML.xsd">
<Accounts>
<Account code="0" searchcode="" status="A" ID="{2723dc8f-33d0-XXXX-9710-XXXXXXXXXXXX}">
</Account>
<Account code="1" searchcode="" status="A" ID="{7c6f362c-79e1-XXXX-8822-XXXXXXXXXXXX}">
</Account>
<Account code="2" searchcode="" status="C" ID="{132c9c6b-dd66-XXXX-b276-XXXXXXXXXXXX}">
<Name>BOB</Name>
<Phone>6845641564564654156454</Phone>
<PhoneExt />
<Fax />
<Email>example@example.com</Email>
<HomePage>example.com<</HomePage>
<Language code="EN" />
<IsSupplier>1</IsSupplier>
<CanDropShip>0</CanDropShip>
<IsBlocked>0</IsBlocked>
<IsReseller>0</IsReseller>
<IsSales>1</IsSales>
<IsPurchase>1</IsPurchase>
<ShowRemarkForSales>0</ShowRemarkForSales>
<Contact number="2090075" gender="M" default="1" ID="{2449ce5d-41b3-XXXX-bab3-XXXXXXXXXXXX}">
<LastName>BOB</LastName>
<MiddleName />
<BirthName>BOB</BirthName>
<BirthNamePrefix />
<PartnerName />
<PartnerNamePrefix />
<FirstName>BOB</FirstName>
<Initials />
<Language code="SAMPLE" />
<Phone>44546456456e</Phone>
<PhoneExt />
<Fax />
<Mobile>eeeeeeeeeeeeeee</Mobile>
<Email>example@example.com</Email>
<BirthPlace />
<IsMailingExcluded>0</IsMailingExcluded>
<Job>
<Description>role</Description>
</Job>
<IsAnonymised>0</IsAnonymised>
</Contact>
<Address type="TES" default="1" ID="{41bde841-afde-XXXX-9cd0-XXXXXXXXXXXX}">
<AddressLine1>sampleroad</AddressLine1>
<AddressLine2 />
<AddressLine3 />
<PostalCode>1000000</PostalCode>
<City>Appels</City>
<State code="O-V" />
<Country code="EN" />
<Phone />
<Fax />
<Contact number="2090075" ID="{2449ce5d-41b3-XXXX-bab3-XXXXXXXXXXXX}" />
</Address>
<VATNumber>VATXXXXXXXX</VATNumber>
<VATLiability>L</VATLiability>
<GovernmentVATSystem>0</GovernmentVATSystem>
<ChamberOfCommerce />
<ChamberOfCommerceEstablishment />
<GlnNumber />
<SalesCurrency code="EUR" />
<PurchaseCurrency code="EUR" />
<CreditLine>
<Sales>0</Sales>
<Purchase>0</Purchase>
</CreditLine>
<Discount>
<SalesPercentage>0.9</SalesPercentage>
<PurchasePercentage>0</PurchasePercentage>
</Discount>
<AccountClassifications />
<IsMailing>0</IsMailing>
<IsCompetitor>0</IsCompetitor>
<StartDate>2020-11-25</StartDate>
<IntraStat>
<System />
<TransactionA />
<TransactionB />
<TransportMethod />
<DeliveryTerm />
<Area />
</IntraStat>
<InvoicingMethod>0</InvoicingMethod>
<IsAnonymised>0</IsAnonymised>
</Account>
</Accounts>
<Topics>
<Topic code="Accounts" ts_d="XXXXXXXXXXXX" count="3" pagesize="1000" />
</Topics>
<Messages />
</eExact>
使用 DOM+Xpath 从 XML 构建数组结构并将其序列化为 JSON。 Xpath 表达式允许您使用位置路径和条件从 DOM 中获取节点列表和标量值。
例如:
- 任何
Account
/eExact/Accounts/Account
- 有
status
C
/eExact/Accounts/Account[@status="C"]
- 只是最后一个节点
(/eExact/Accounts/Account[@status="C"])[last()]
位置路径开头的 /
将其锚定到文档,否则表达式将使用当前上下文(DOMXpath::evaluate()
的第二个参数)。
例如:
- 任何
Email
子元素
Email
- 将第一个找到的
Email
转换为字符串
string(Email)
演示:
$document = new DOMDocument();
$document->loadXML(getXML());
$xpath = new DOMxpath($document);
$json = [];
foreach ($xpath->evaluate('(/eExact/Accounts/Account[@status="C"])[last()]') as $account) {
$json['email'] = $xpath->evaluate('string(Email)', $account);
$json['username'] = $xpath->evaluate('string(Name)', $account);
$json['first_name'] = $xpath->evaluate('string(Contact[@default="1"]/FirstName)', $account);
$json['last_name'] = $xpath->evaluate('string(Contact[@default="1"]/LastName)', $account);
$json['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),
];
// ...
}
echo json_encode($json, JSON_PRETTY_PRINT);
输出:
{
"email": "example@example.com",
"username": "BOB",
"first_name": "BOB",
"last_name": "BOB",
"billing": {
"first_name": "BOB",
"last_name": "BOB",
"postcode": "1000000"
}
}
我遇到了一个问题。我正在尝试编写一个应用程序,它基本上从包含客户的在线 XML 文件中读取和排序数据,并在 Wordpress/woocommerce 到 cURL/php/JSON 中重新创建这些客户。我正在使用 insomnia 来测试我的调用和代码片段。
这是我目前得到的:
- 将客户数据从在线数据库中提取到 xml[但其原始未分类且信息过多]
- 通过 JSON/PHP/cURL 中的 POST 请求在 Woocommerce/Wordpress 中创建客户
我目前缺少将 XML 数据分类为 table 和将该数据填充到一段代码中的桥梁,该代码包含通过 REST [=58] 将所述数据重新创建到 woocommerce 中的变量=].
简而言之,我想:
将客户数据拉入 XML - OK
读取XML客户数据并将其赋值给变量
使用上述变量在 Woocommerce/wordpress 中推送和重新创建客户。
我该如何处理?
这就是我在 woocommerce 中创建客户的方式。基本上 CURL_POSTFIELDS
标签应该包含来自该客户 XML table 的一行及其分配数据。
<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://www.testsite.com/wp-json/wc/v3/customers?consumer_key=XXXXXXXXXXXX&consumer_secret=XXXXXXXXXXXXXXXXX",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => "{\n \"email\": \"john.doe@example.com\",\n \"first_name\": \"John\",\n \"last_name\": \"Doe\",\n \"username\": \"john.doe\",\n \"billing\": {\n \"first_name\": \"John\",\n \"last_name\": \"Doe\",\n \"company\": \"\",\n \"address_1\": \"969 Market\",\n \"address_2\": \"\",\n \"city\": \"San Francisco\",\n \"state\": \"CA\",\n \"postcode\": \"94103\",\n \"country\": \"US\",\n \"email\": \"john.doe@example.com\",\n \"phone\": \"(555) 555-5555\"\n },\n \"shipping\": {\n \"first_name\": \"John\",\n \"last_name\": \"Doe\",\n \"company\": \"\",\n \"address_1\": \"969 Market\",\n \"address_2\": \"\",\n \"city\": \"San Francisco\",\n \"state\": \"CA\",\n \"postcode\": \"94103\",\n \"country\": \"US\"\n }\n}",
CURLOPT_HTTPHEADER => [
"Authorization: Basic Og==",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
insomania 中的 JSON 有这些作为输入,与上面相同的故事,它应该用 XML:
中的客户数据填充{
"email": "john.doe@example.com",
"first_name": "John",
"last_name": "Doe",
"username": "john.doe",
"billing": {
"first_name": "John",
"last_name": "Doe",
"company": "",
"address_1": "969 Market",
"address_2": "",
"city": "San Francisco",
"state": "CA",
"postcode": "94103",
"country": "US",
"email": "john.doe@example.com",
"phone": "(555) 555-5555"
},
"shipping": {
"first_name": "John",
"last_name": "Doe",
"company": "",
"address_1": "969 Market",
"address_2": "",
"city": "San Francisco",
"state": "CA",
"postcode": "94103",
"country": "US"
}
}
这是 XML 数据的响应示例。我已展开帐户代码 2 以显示其内容。显然我不想要它的所有内容,我只对姓名、电子邮件、地址、phone 和增值税号感兴趣。
<eExact
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="eExact-XML.xsd">
<Accounts>
<Account code="0" searchcode="" status="A" ID="{2723dc8f-33d0-XXXX-9710-XXXXXXXXXXXX}">
</Account>
<Account code="1" searchcode="" status="A" ID="{7c6f362c-79e1-XXXX-8822-XXXXXXXXXXXX}">
</Account>
<Account code="2" searchcode="" status="C" ID="{132c9c6b-dd66-XXXX-b276-XXXXXXXXXXXX}">
<Name>BOB</Name>
<Phone>6845641564564654156454</Phone>
<PhoneExt />
<Fax />
<Email>example@example.com</Email>
<HomePage>example.com<</HomePage>
<Language code="EN" />
<IsSupplier>1</IsSupplier>
<CanDropShip>0</CanDropShip>
<IsBlocked>0</IsBlocked>
<IsReseller>0</IsReseller>
<IsSales>1</IsSales>
<IsPurchase>1</IsPurchase>
<ShowRemarkForSales>0</ShowRemarkForSales>
<Contact number="2090075" gender="M" default="1" ID="{2449ce5d-41b3-XXXX-bab3-XXXXXXXXXXXX}">
<LastName>BOB</LastName>
<MiddleName />
<BirthName>BOB</BirthName>
<BirthNamePrefix />
<PartnerName />
<PartnerNamePrefix />
<FirstName>BOB</FirstName>
<Initials />
<Language code="SAMPLE" />
<Phone>44546456456e</Phone>
<PhoneExt />
<Fax />
<Mobile>eeeeeeeeeeeeeee</Mobile>
<Email>example@example.com</Email>
<BirthPlace />
<IsMailingExcluded>0</IsMailingExcluded>
<Job>
<Description>role</Description>
</Job>
<IsAnonymised>0</IsAnonymised>
</Contact>
<Address type="TES" default="1" ID="{41bde841-afde-XXXX-9cd0-XXXXXXXXXXXX}">
<AddressLine1>sampleroad</AddressLine1>
<AddressLine2 />
<AddressLine3 />
<PostalCode>1000000</PostalCode>
<City>Appels</City>
<State code="O-V" />
<Country code="EN" />
<Phone />
<Fax />
<Contact number="2090075" ID="{2449ce5d-41b3-XXXX-bab3-XXXXXXXXXXXX}" />
</Address>
<VATNumber>VATXXXXXXXX</VATNumber>
<VATLiability>L</VATLiability>
<GovernmentVATSystem>0</GovernmentVATSystem>
<ChamberOfCommerce />
<ChamberOfCommerceEstablishment />
<GlnNumber />
<SalesCurrency code="EUR" />
<PurchaseCurrency code="EUR" />
<CreditLine>
<Sales>0</Sales>
<Purchase>0</Purchase>
</CreditLine>
<Discount>
<SalesPercentage>0.9</SalesPercentage>
<PurchasePercentage>0</PurchasePercentage>
</Discount>
<AccountClassifications />
<IsMailing>0</IsMailing>
<IsCompetitor>0</IsCompetitor>
<StartDate>2020-11-25</StartDate>
<IntraStat>
<System />
<TransactionA />
<TransactionB />
<TransportMethod />
<DeliveryTerm />
<Area />
</IntraStat>
<InvoicingMethod>0</InvoicingMethod>
<IsAnonymised>0</IsAnonymised>
</Account>
</Accounts>
<Topics>
<Topic code="Accounts" ts_d="XXXXXXXXXXXX" count="3" pagesize="1000" />
</Topics>
<Messages />
</eExact>
使用 DOM+Xpath 从 XML 构建数组结构并将其序列化为 JSON。 Xpath 表达式允许您使用位置路径和条件从 DOM 中获取节点列表和标量值。
例如:
- 任何
Account
/eExact/Accounts/Account
- 有
status
C
/eExact/Accounts/Account[@status="C"]
- 只是最后一个节点
(/eExact/Accounts/Account[@status="C"])[last()]
位置路径开头的 /
将其锚定到文档,否则表达式将使用当前上下文(DOMXpath::evaluate()
的第二个参数)。
例如:
- 任何
Email
子元素Email
- 将第一个找到的
Email
转换为字符串string(Email)
演示:
$document = new DOMDocument();
$document->loadXML(getXML());
$xpath = new DOMxpath($document);
$json = [];
foreach ($xpath->evaluate('(/eExact/Accounts/Account[@status="C"])[last()]') as $account) {
$json['email'] = $xpath->evaluate('string(Email)', $account);
$json['username'] = $xpath->evaluate('string(Name)', $account);
$json['first_name'] = $xpath->evaluate('string(Contact[@default="1"]/FirstName)', $account);
$json['last_name'] = $xpath->evaluate('string(Contact[@default="1"]/LastName)', $account);
$json['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),
];
// ...
}
echo json_encode($json, JSON_PRETTY_PRINT);
输出:
{
"email": "example@example.com",
"username": "BOB",
"first_name": "BOB",
"last_name": "BOB",
"billing": {
"first_name": "BOB",
"last_name": "BOB",
"postcode": "1000000"
}
}