你能帮我解析这个带PHP的XML吗?

时间:2017-07-18 14:48:37

标签: php xml dom

我正在尝试为我们的PSA软件编写付款和Xero集成。由于这里的帮助,计费部分已经相当不错了。现在有趣的部分来自:将PSA的API中的发票数据解析为可以提供给Xero的可用数据......

以下是来自API的XML:

<invoice_batch_generic xmlns="http://tempuri.org/invoice_batch_generic.xsd">
    <invoice_batch>
        <batch_id>171</batch_id>
        <create_date>2017-07-11T14:23:39.133-04:00</create_date>
        <create_by_id>29682885</create_by_id>
        <batch_data />
    </invoice_batch>
    <taxregioncategory>
        <tax_category_name />
        <total_tax_rate_per_category_and_region>0.0000000</total_tax_rate_per_category_and_region>
        <total_tax_amount>0.00000</total_tax_amount>
    </taxregioncategory>
    <account>
        <account_id>232</account_id>
        <parent_name />
        <creator_name>Dominic</creator_name>
        <narrative_creator_name>Dominic</narrative_creator_name>
        <territory_name />
        <cust_id />
        <cust_name>Metro </cust_name>
        <taxable>No</taxable>
        <addr1>123 Anywhere Ln</addr1>
        <addr2 />
        <city>Denver</city>
        <account_region>CO</account_region>
        <country>United States</country>
        <postal_code>80203</postal_code>
        <phone>1234567890</phone>
        <fax />
        <attention />
        <billing_addr1>132 anywhere ln</billing_addr1>
        <billing_addr2 />
        <billing_city>Denver</billing_city>
        <billing_region>CO</billing_region>
        <billing_country>United States</billing_country>
        <billing_postal_code>80203</billing_postal_code>
        <billing_attention />
        <tax_id />
        <tax_group_name />
        <parent_id />
        <payment_term_name>NET 15</payment_term_name>
        <account_invoice_email_recipient></account_invoice_email_recipient>
        <invoice>
            <invoice_id>471</invoice_id>
            <account_id>232</account_id>
            <owner_name>Dominic</owner_name>
            <narrative_owner_name>Dominic</narrative_owner_name>
            <invoice_date>2017-07-11T00:00:00-04:00</invoice_date>
            <entry_time_stamp>2017-07-11T14:23:39-04:00</entry_time_stamp>
            <invoice_number>2374</invoice_number>
            <comments />
            <invoice_total>1087.0800</invoice_total>
            <total_tax_value>0.0000</total_tax_value>
            <tax_description />
            <tax_group />
            <date_range_from>2017-08-01T00:00:00-04:00</date_range_from>
            <date_range_to>2017-08-30T00:00:00-04:00</date_range_to>
            <purchase_order_number />
            <payment_term_name>NET 15</payment_term_name>
            <batch_id>171</batch_id>
            <invoice_transferred_flag>No</invoice_transferred_flag>
            <payment_due_date>2017-07-26T00:00:00-04:00</payment_due_date>
            <taxes />
            <invoice_item>
                <invoice_item_id>1</invoice_item_id>
                <invoice_id>471</invoice_id>
                <item_name>SOME STUFF</item_name>
                <item_id>9234</item_id>
                <item_date>2017-08-01T00:00:00-04:00</item_date>
                <adjusted_item_id />
                <type_of_transaction>Recurring Service</type_of_transaction>
                <allocation_code_name>Managed Services</allocation_code_name>
                <allocation_code_external_number />
                <allocation_code_non_billable>No</allocation_code_non_billable>
                <allocation_code_taxable>No</allocation_code_taxable>
                <task_or_ticket_number />
                <task_or_ticket_title>Recurring Service</task_or_ticket_title>
                <ticket_contact />
                <narrative_ticket_contact />
                <adjustment_reason />
                <resource_name> Dominic</resource_name>
                <narrative_resource_name>Dominic </narrative_resource_name>
                <resource_payroll_identifier />
                <role_name />
                <department>Operations</department>
                <project_name />
                <project_lead />
                <narrative_project_lead />
                <external_project_number />
                <internal_project_number />
                <gl_code_desc />
                <gl_code_name />
                <contract_name>Metro 2017</contract_name>
                <external_contract_number />
                <worked_hours>0.0000</worked_hours>
                <non_billable_hours>0.0000</non_billable_hours>
                <billable_hours>0.0000</billable_hours>
                <hourly_billing_rate>21.4800</hourly_billing_rate>
                <extended_price>859.2000</extended_price>
                <time_entry_summary_notes />
                <quantity>40.0000</quantity>
                <expense_type />
                <installed_product_name />
                <subscription_name />
                <subscription_desc />
                <subscription_cost>0.00</subscription_cost>
                <milestone_title />
                <milestone_description />
                <milestone_amount>0.0000</milestone_amount>
                <service_or_bundle_id>63</service_or_bundle_id>
                <service_name>STUFF</service_name>
                <service_invoice_description>STUFF</service_invoice_description>
                <service_units>40</service_units>
                <service_unit_price>21.4800</service_unit_price>
                <service_extended_price>859.2000</service_extended_price>
                <service_period_start_date>2017-08-01T00:00:00-04:00</service_period_start_date>
                <service_period_end_date>2017-08-31T00:00:00-04:00</service_period_end_date>
                <setup_fee>0.0000</setup_fee>
                <billing_approved_by>, Dominic</billing_approved_by>
                <narrative_billing_approved_by>Dominic </narrative_billing_approved_by>
                <approved_date>2017-07-11T11:03:25.957-04:00</approved_date>
                <posted_date>2017-07-10T20:00:00-04:00</posted_date>
                <non_overage_retainer_line_item_tax>0.0000</non_overage_retainer_line_item_tax>
                <gross_amount>859.2000</gross_amount>
                <contract_type>7</contract_type>
                <department_number />
                <effective_hourly_billing_rate>21.4800</effective_hourly_billing_rate>
                <external_product_id />
                <cost_description />
                <project_phase />
                <our_cost>310.0000</our_cost>
                <expense_description />
                <line_item_id>1</line_item_id>
                <tax_region_and_category_id>0</tax_region_and_category_id>
                <tax_region_name />
                <tax_category_name />
                <total_tax_rate_per_region_and_category>0.0000000</total_tax_rate_per_region_and_category>
                <total_tax_amount>0.00000</total_tax_amount>
                <allocation_code_id>29682901</allocation_code_id>
                <serial_number />
                <contract_period_type>m</contract_period_type>
                <service_period_type>m</service_period_type>
                <account_manager_when_posted>, Dominic</account_manager_when_posted>
            </invoice_item>
            <invoice_item>
                <invoice_item_id>2</invoice_item_id>
                <invoice_id>471</invoice_id>
                <item_name>SEServer [Aug 01, 2017 - Aug 31, 2017]</item_name>
                <item_id>9235</item_id>
                <item_date>2017-08-01T00:00:00-04:00</item_date>
                <adjusted_item_id />
                <type_of_transaction>Recurring Service</type_of_transaction>
                <allocation_code_name>Managed Services</allocation_code_name>
                <allocation_code_external_number />
                <allocation_code_non_billable>No</allocation_code_non_billable>
                <allocation_code_taxable>No</allocation_code_taxable>
                <task_or_ticket_number />
                <task_or_ticket_title>Recurring Service</task_or_ticket_title>
                <ticket_contact />
                <narrative_ticket_contact />
                <adjustment_reason />
                <resource_name>, Dominic</resource_name>
                <narrative_resource_name>Dominic </narrative_resource_name>
                <resource_payroll_identifier />
                <role_name />
                <department>Operations</department>
                <project_name />
                <project_lead />
                <narrative_project_lead />
                <external_project_number />
                <internal_project_number />
                <gl_code_desc />
                <gl_code_name />
                <contract_name>Metro  2017</contract_name>
                <external_contract_number />
                <worked_hours>0.0000</worked_hours>
                <non_billable_hours>0.0000</non_billable_hours>
                <billable_hours>0.0000</billable_hours>
                <hourly_billing_rate>110.4800</hourly_billing_rate>
                <extended_price>220.9600</extended_price>
                <time_entry_summary_notes />
                <quantity>2.0000</quantity>
                <expense_type />
                <installed_product_name />
                <subscription_name />
                <subscription_desc />
                <subscription_cost>0.00</subscription_cost>
                <milestone_title />
                <milestone_description />
                <milestone_amount>0.0000</milestone_amount>
                <service_or_bundle_id>62</service_or_bundle_id>
                <service_name>SECURE MANAGED SERVICES: Server</service_name>
                <service_invoice_description>Secure Managed Services Per Server</service_invoice_description>
                <service_units>2</service_units>
                <service_unit_price>110.4800</service_unit_price>
                <service_extended_price>220.9600</service_extended_price>
                <service_period_start_date>2017-08-01T00:00:00-04:00</service_period_start_date>
                <service_period_end_date>2017-08-31T00:00:00-04:00</service_period_end_date>
                <setup_fee>0.0000</setup_fee>
                <billing_approved_by>, Dominic</billing_approved_by>
                <narrative_billing_approved_by> Kirby</narrative_billing_approved_by>
                <approved_date>2017-07-11T11:03:25.957-04:00</approved_date>
                <posted_date>2017-07-10T20:00:00-04:00</posted_date>
                <non_overage_retainer_line_item_tax>0.0000</non_overage_retainer_line_item_tax>
                <gross_amount>220.9600</gross_amount>
                <contract_type>7</contract_type>
                <department_number />
                <effective_hourly_billing_rate>110.4800</effective_hourly_billing_rate>
                <external_product_id />
                <cost_description />
                <project_phase />
                <our_cost>91.5000</our_cost>
                <expense_description />
                <line_item_id>2</line_item_id>
                <tax_region_and_category_id>0</tax_region_and_category_id>
                <tax_region_name />
                <tax_category_name />
                <total_tax_rate_per_region_and_category>0.0000000</total_tax_rate_per_region_and_category>
                <total_tax_amount>0.00000</total_tax_amount>
                <allocation_code_id>29682901</allocation_code_id>
                <serial_number />
                <contract_period_type>m</contract_period_type>
                <service_period_type>m</service_period_type>
                <account_manager_when_posted>, Dominic</account_manager_when_posted>
            </invoice_item>
            <invoice_item>
                <invoice_item_id>3</invoice_item_id>
                <invoice_id>471</invoice_id>
                <item_name>SECURE MANAGED SERVICES: Firewall  [Aug 01, 2017 - Aug 31, 2017]</item_name>
                <item_id>9236</item_id>
                <item_date>2017-08-01T00:00:00-04:00</item_date>
                <adjusted_item_id />
                <type_of_transaction>Recurring Service</type_of_transaction>
                <allocation_code_name>Hardware as a Service</allocation_code_name>
                <allocation_code_external_number>HWAAS</allocation_code_external_number>
                <allocation_code_non_billable>No</allocation_code_non_billable>
                <allocation_code_taxable>No</allocation_code_taxable>
                <task_or_ticket_number />
                <task_or_ticket_title>Recurring Service</task_or_ticket_title>
                <ticket_contact />
                <narrative_ticket_contact />
                <adjustment_reason />
                <resource_name>, Dominic</resource_name>
                <narrative_resource_name>Dominic </narrative_resource_name>
                <resource_payroll_identifier />
                <role_name />
                <department>Operations</department>
                <project_name />
                <project_lead />
                <narrative_project_lead />
                <external_project_number />
                <internal_project_number />
                <gl_code_desc />
                <gl_code_name />
                <contract_name>Metro  2017</contract_name>
                <external_contract_number />
                <worked_hours>0.0000</worked_hours>
                <non_billable_hours>0.0000</non_billable_hours>
                <billable_hours>0.0000</billable_hours>
                <hourly_billing_rate>6.9200</hourly_billing_rate>
                <extended_price>6.9200</extended_price>
                <time_entry_summary_notes />
                <quantity>1.0000</quantity>
                <expense_type />
                <installed_product_name />
                <subscription_name />
                <subscription_desc />
                <subscription_cost>0.00</subscription_cost>
                <milestone_title />
                <milestone_description />
                <milestone_amount>0.0000</milestone_amount>
                <service_or_bundle_id>64</service_or_bundle_id>
                <service_name>SECURE MANAGED SERVICES: Firewall TZ300</service_name>
                <service_invoice_description>SonicWALL TZ300 Managed Firewall</service_invoice_description>
                <service_units>1</service_units>
                <service_unit_price>6.9200</service_unit_price>
                <service_extended_price>6.9200</service_extended_price>
                <service_period_start_date>2017-08-01T00:00:00-04:00</service_period_start_date>
                <service_period_end_date>2017-08-31T00:00:00-04:00</service_period_end_date>
                <setup_fee>0.0000</setup_fee>
                <billing_approved_by>, Dominic</billing_approved_by>
                <narrative_billing_approved_by>Dominic </narrative_billing_approved_by>
                <approved_date>2017-07-11T11:03:25.957-04:00</approved_date>
                <posted_date>2017-07-10T20:00:00-04:00</posted_date>
                <non_overage_retainer_line_item_tax>0.0000</non_overage_retainer_line_item_tax>
                <gross_amount>6.9200</gross_amount>
                <contract_type>7</contract_type>
                <department_number />
                <effective_hourly_billing_rate>6.9200</effective_hourly_billing_rate>
                <external_product_id />
                <cost_description />
                <project_phase />
                <our_cost>46.0000</our_cost>
                <expense_description />
                <line_item_id>3</line_item_id>
                <tax_region_and_category_id>0</tax_region_and_category_id>
                <tax_region_name />
                <tax_category_name />
                <total_tax_rate_per_region_and_category>0.0000000</total_tax_rate_per_region_and_category>
                <total_tax_amount>0.00000</total_tax_amount>
                <allocation_code_id>29683499</allocation_code_id>
                <serial_number />
                <contract_period_type>m</contract_period_type>
                <service_period_type>m</service_period_type>
                <account_manager_when_posted>, Dominic</account_manager_when_posted>
            </invoice_item>
        </invoice>
    </account>
</invoice_batch_generic>

基本上,我需要从这个XML中获取某些数据:

  • INVOICE_NUMBER
  • total_tax_rate_per_category_and_region
  • total_tax_ammount
  • 然后对于每个invoice_item,我需要创建一个数组:
  • ITEM_NAME
  • allocation_code_external_number
  • hourly_billing_rate
  • service_unit_price

不幸的是,我的XML解析经验不存在。这个API提供其他所有内容,因为它很容易解析对象......我不是要求有人为我写这个,只是希望得到一个指向正确方向的指针。在这里,我试图解析一些项目:

//THIS IS WHERE WE PULL THE XML FROM OUR API
$xmlMarkup = $AT_Client->getInvoiceMarkup($_GET['Invoice'], 'XML');
$xmlMarkupResult = $xmlMarkup->GetInvoiceMarkupResult;

//THIS IS WHERE I WANT TO PARSE THINGS INTO VALUES THAT I CAN FEED INTO XERO

$dom = new DomDocument("1.0", "ISO-8859-1");
$dom->loadXml{$xmlMarkupResult};
$xpath = new DOMXPath($dom);

$itemList = array();
$itemNodes = $xpath->query('//account/invoice/invoice_item');
for($i=0;$i<$itemNodes->length;$i++) {
    $itemList[] = $itemNodes->item($i)->nodeValue;
}

print_r($itemList);

非常感谢任何指导!

2 个答案:

答案 0 :(得分:-1)

在DOM扩展中最强大的部分,它是与XPath的集成 - 事实上,DomXPath比SimpleXML等效功能强大得多。这个例子看起来相当复杂,但实际上它显示了DOM XPath功能的灵活性。

$dom = new DOMDocument("1.0", "UTF-8");
$dom->preserveWhiteSpace = false;

$dom->loadXml($xmlMarkupResult);
$xpath = new DOMXPath($dom);
$xpath->registerNamespace("ns", "http://tempuri.org/invoice_batch_generic.xsd");

$rootNode = $xpath->query('/ns:invoice_batch_generic')->item(0);

// Invoice data
$invoiceNumber = $xpath->query('ns:account/ns:invoice/ns:invoice_number', $rootNode)->item(0)->nodeValue;
$taxRate = $xpath->query('ns:taxregioncategory/ns:total_tax_rate_per_category_and_region', $rootNode)->item(0)->nodeValue;
$totalTaxAmount = $xpath->query('ns:taxregioncategory/ns:total_tax_amount', $rootNode)->item(0)->nodeValue;

// Invoice items
$itemList = array();
$invoiceItemNodes = $xpath->query('ns:account/ns:invoice/ns:invoice_item', $rootNode);

/* @var $invoiceItemNode DOMNode */
foreach ($invoiceItemNodes as $invoiceItemNode) {
    $row = [];

    /* @var $field DOMNode */
    foreach ($invoiceItemNode->childNodes as $field) {
        $row[$field->tagName] = $field->nodeValue;
    }
    $itemList[] = $row;
}

print_r($itemList);

答案 1 :(得分:-1)

使用SimpleXML可以更直接地访问数据,并且(IMHO)逻辑。由于这是一个相当简单的结构,你可以使用类似......

的东西
$xml = simplexml_load_file("t1.xml");

foreach ($xml->account->invoice as $invoice) {
    echo "Invoice id:".$invoice->invoice_id."\n";
    foreach ( $invoice->invoice_item as $item ) {
        echo "total_tax_rate_per_region_and_category:".
                (string)$item->total_tax_rate_per_region_and_category."\n";
        echo "total_tax_amount:".
                (string)$item->total_tax_amount."\n";
    }
}

如您所见,load_file只读取数据,然后您可以使用各种级别的数据,就像访问对象的元素一样。我希望这对你来说已经足够了。

我要指出的一件事是,当访问元素时,转换为(string)会返回元素的值,而仅使用元素名称就是对象。