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

问题描述:

我有点被一个问题困住了.我正在尝试编写一个应用程序,该应用程序从包含客户的在线 XML 文件中读取和排序数据,并通过 cURL/php/JSON 在 Wordpress/woocommerce 中重新创建这些客户.我使用 insomnia 来测试我的调用和代码片段.

I'm somewhat stuck on a problem. I'm attempting to write an app that bascially reads and sorts DATA from an online XML file containing customers and recreates those customers in Wordpress/woocommerce through cURL/php/JSON. Im using insomnia to test my calls and code pieces.

这是我目前得到的:

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

我目前缺少将 XML 数据排序到表格中和将该数据填充到包含变量的代码段之间的桥梁,该代码段通过 REST API 将所述数据重新创建到 woocommerce 中.

Im currently missing the bridge between sorting the XML data into a table and having that data be filled into a piece of code containing variables that recreates said data into woocommerce through REST API.

简而言之,我想:

1.Pull Customer data into XML - OK

1.Pull Customer data into XML - OK

2.读取 XML 客户数据并将其分配给变量

2.Read the XML customer data and assign it to varriables

3. 使用上述变量在 Woocommerce/wordpress 中推送和重新创建客户.

3.Use said variables to push and recreate customers in Woocommerce/wordpress.

我应该如何处理这个问题?

How should i approach this ?

这就是我在 woocommerce 中创建客户的方式.基本上,CURL_POSTFIELDS 标签应该包含来自该客户 XML 表的一行及其分配数据.

this is how i create a customer in woocommerce. Bascially the CURL_POSTFIELDS tags should contain a single line from that customer XML table with its assign data.

<?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 的客户数据

The JSON in insomania has these as input, same story as above, it should be filled with the customer data form the 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 以显示其内容.obv 我不想要它的所有内容,我只对姓名、电子邮件、地址、电话和增值税号感兴趣.

Here is a sample of the response from the XML data. i've expanded account code 2 to show its contents. obv i dont want everything from it, im only interested in name,email,adress,phone and VAT number for instance.

<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 中获取节点列表和标量值.

Build an array structure from the XML using DOM+Xpath and serialize it to JSON. Xpath expressions allow you to fetch node list and scalar values from the DOM using location paths and conditions.

例如:

  • 任何账户
    /eExact/Accounts/Account
  • 具有status C
    /eExact/Accounts/Account[@status=C"]
  • 只是最后一个节点
    (/eExact/Accounts/Account[@status=C"])[last()]

位置路径开头的 / 将其锚定到文档,否则表达式将使用当前上下文(DOMXpath::evaluate() 的第二个参数).

The / at the start of the location path anchors it to the document otherwise the expression will use the current context (the second argument of DOMXpath::evaluate()).

例如:

  • 任何Email子元素
    Email
  • cast first found Email to string
    string(Email)
  • any Email child element
    Email
  • cast first found Email to string
    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"
    }
}