问题
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.
This is what i got so far:
- Pull customer data from the online database into xml [ but its raw unsorted and too much info ]
- Create a customer in Woocommerce/ Wordpress by POST request in JSON/PHP/cURL
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.
Shortly said, i want to:
1.Pull Customer data into XML - OK
2.Read the XML customer data and assign it to varriables
3.Use said variables to push and recreate customers in Woocommerce/wordpress.
How should i approach this ?
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;
}
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"
}
}
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>
回答1:
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.
For example:
- any
Account
/eExact/Accounts/Account
- that has the
status
C
/eExact/Accounts/Account[@status="C"]
- just the last node
(/eExact/Accounts/Account[@status="C"])[last()]
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()
).
For example:
- any
Email
child elementEmail
- cast first found
Email
to stringstring(Email)
Demo:
$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);
Output:
{
"email": "example@example.com",
"username": "BOB",
"first_name": "BOB",
"last_name": "BOB",
"billing": {
"first_name": "BOB",
"last_name": "BOB",
"postcode": "1000000"
}
}
来源:https://stackoverflow.com/questions/65291311/push-xml-data-to-rest-api-with-php-curl-json