使用 PHP/cURL/JSON 将 XML 数据推送到 REST API

Push XML DATA to REST API with PHP/cURL/JSON

我遇到了一个问题。我正在尝试编写一个应用程序,它基本上从包含客户的在线 XML 文件中读取和排序数据,并在 Wordpress/woocommerce 到 cURL/php/JSON 中重新创建这些客户。我正在使用 insomnia 来测试我的调用和代码片段。

这是我目前得到的:

  1. 将客户数据从在线数据库中提取到 xml[但其原始未分类且信息过多]
  2. 通过 JSON/PHP/cURL
  3. 中的 POST 请求在 Woocommerce/Wordpress 中创建客户

我目前缺少将 XML 数据分类为 table 和将该数据填充到一段代码中的桥梁,该代码包含通过 REST [=58] 将所述数据重新创建到 woocommerce 中的变量=].


简而言之,我想:

  1. 将客户数据拉入 XML - OK

  2. 读取XML客户数据并将其赋值给变量

  3. 使用上述变量在 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
  • statusC
    /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"
    }
}