好的,我遇到了一个很大的问题,没有多少时间来修复它。我们有多个需要编辑的XML文件。我已经能够使用PHP获取数据,进行计算,并将其存储在变量中,但现在我被卡住了。我需要将该变量返回到XML文件中,但它会在文件中多次发生。以下是我的PHP代码:
<?php
//Change debug to value greater than 0 for debugging; make it greater than 5 for seeing all the arrays
$debug=0;
$file="test.xml";
$newfile = "filetemp.txt";
copy($file, $newfile) or exit("failed to copy $file");
$z = new XMLReader;
$z->open('test.xml');
$doc = new DOMDocument;
// move to the first <invoice /> node
while ($z->read() && $z->name !== 'invoice');
// now that we're at the right depth, hop to the next <invoice /> until the end of the tree
while ($z->name === 'invoice') {
//the tot_array gathers the fund summary data into this array
//this is needed in order to calculate the prorated shipping charges
$tot_array=array();
// either one should work
//$node = new SimpleXMLElement($z->readOuterXML());
$node = simplexml_import_dom($doc->importNode($z->expand(), true));
if ($debug > 5) { print_r($node); }
//initialize the check variable
$check=null;
//this foreach checks for invoices that have "proratedByLine" - trying to reduce processing by reducing the number of records need to examine
foreach ($node->invoiceLine as $atts) {
if ($atts->attributes() == "proratedByLine") {
if ($debug > 0) { echo "Yes", PHP_EOL; }
$check="yes";
} else {
if ($debug > 0) { echo "No", PHP_EOL; }
$check="no";
}
}
if ($debug > 0) { echo "Check --> ".$check, PHP_EOL; }
if ($check == "yes") {
// now you can use $node without going insane about parsing
//var_dump($node->invoiceID);
echo "InvoiceID: ".$node->invoiceID, PHP_EOL;
//this foreach assigns the $tot_array variable the fund summary data from the invoice
foreach ($node->fundSummary->fund as $funds) {
$tot_array["$funds->fundID"]=$funds->amountPaid;
}
//initialize $x, $y, and $sortable_array variables;
$x=0; $y=0; $sortable_array=null;
//assign sortable_array variable as an array
$sortable_array=array();
//this foreach stores the individual invoiceLine "fundId | amout paid" into an array, to be used to compare with the fund summary array (tot_array)
foreach ($node->invoiceLine as $atts) {
if ($debug > 5) { print_r($atts); }
if ($atts->attributes() == "orderLine") {
if ($debug > 0) { echo "FundID: ".$atts->fundID,PHP_EOL; }
$sortable_array["$x"]=$atts->fundID."|".$atts->amountInvoiced->vendorAmountPaid;
$xx=$atts->fundID;
}
$x=$x+1;
}
//this count variable is used to find the last invoiceLine in the invoice - always the prorated line (shipping)
$count=$x-1;
if ($debug > 0) { echo "Count: ".$count, PHP_EOL; }
//need to sort the "fundId|amount paid" array in order to calculate total
sort($sortable_array);
if ($debug > 5) { print_r($tot_array); print_r($sortable_array); }
//this section sums the "fundId|amount paid" into the fund2 array
$xx=0;
$x=null;
$tot=0;
$fund2=array();
foreach($sortable_array as $key=>$value) {
if ($debug > 0) { echo "key: ".$key."; value: ".$value, PHP_EOL; }
list($fund,$amt)=explode("|",$value);
if ($fund == $x) {
$tot=$tot+$amt;
if ($debug > 0) { echo "Fund1: ".$fund."; Amount: ".$tot, PHP_EOL; }
} else {
$tot=$amt;
$x=$fund;
if ($debug > 0) { echo "Fund2: ".$fund."; Amount: ".$amt, PHP_EOL; }
}
$fund2["$x"]=$tot;
}
if ($debug > 5) { print_r($fund2); }
//this section calculates the actual prorated shipping charges per fund and stores it in the $entry variable as XML
//initialize the prov, insert, entry, library, fyear, and entry variables
$prov=0; $insert=array(); $entry=null; $library=null; $fyear=null; $entry=PHP_EOL;
foreach($tot_array as $key=>$value) {
if ($debug > 0) { echo "Key: ".$key."; Value: ".$value, PHP_EOL; }
foreach($fund2 as $key2=>$value2) {
if ($debug > 0) { echo "Key2: ".$key2."; Value2: ".$value2, PHP_EOL; }
if ($key == $key2) {
//have to assign the value variables to the float type in order to calculate correctly
settype($value, "float");
settype($value2, "float");
if ($debug > 0) { echo "Value (".$value.") minus Value2 (".$value2.")",PHP_EOL; }
$prov=$value-$value2;
$entry .= "<fundID>".$key."</fundID>".PHP_EOL;
$entry .= "<fundLibrary>".$library."</fundLibrary>".PHP_EOL;
$entry .= "<fiscalCycle>".$fyear."</fiscalCycle>".PHP_EOL;
$entry .= "<vendorFinalPrice currency=\"$\">".$prov."</vendorFinalPrice>".PHP_EOL;
}
}
}
/*
//None of the below works
foreach($lines as $line) {
if (strstr($line,$key)) { //look for $key in each
fwrite($f,$newline."\n"); //insert data before line with key
}
fwrite($f,$line); //place $line back in file
}
$string = 'I am happy today.';
$replacement = 'very ';
echo substr_replace($string, $replacement, 4, 0); // I am very happy today.
//appendChild not available in Windows version of PHP
$node->invoiceLine[$count]->appendChild('funds', $entry);
//the below two lines wipes out the original file and only maintains the last invoice with the changes; can't do that
$node->invoiceLine[$count]->funds = $entry;
$node->asXML($file);
//the below works in Linux but not Windows
$cmd = "cat $file| sed -e 's/</</g' -e 's/>/>/g' > newfile.txt";
$cmd2 = "mv newfile.txt $file";
exec($cmd);
exec($cmd2);
*/
} //end invoice check for prorated line
// go to next <invoice />
$z->next('invoice');
} //end while statement
//the below line does not work - only inserts the last invoice into the file; does not include all invoices from the file
//$node->asXML($file);
?>
这是我正在反对的XML:
<?xml version="1.0" encoding="UTF-8"?>
<report>
<dateCreated>2018-05-29T16:04:22</dateCreated>
<dateFormat>mm/dd/yyyy</dateFormat>
<invoice>
<library>BIOMEDICAL</library>
<invoiceID>A530303</invoiceID>
<vendorID>MAJORSB</vendorID>
<invoiceControlNumber> 1</invoiceControlNumber>
<createdInFiscalCycle>1997</createdInFiscalCycle>
<fundSummary>
<fund>
<fundID>48020000</fundID>
<fiscalCycle>1997</fiscalCycle>
<accountNumber>1536950000,74500</accountNumber>
<amountInvoiced currency="$">0.00</amountInvoiced>
<amountPaid currency="$">373.88</amountPaid>
</fund>
</fundSummary>
<numberOfLines>6</numberOfLines>
<numberOfLinesPaid>6</numberOfLinesPaid>
<numberOfCopies>6</numberOfCopies>
<numberOfCopiesPaid>6</numberOfCopiesPaid>
<invoiceLine lineType="orderLine">
<lineNumber>1</lineNumber>
<amountInvoiced>
<vendorAmount currency="$">35.16</vendorAmount>
<vendorAmountPaid currency="$">35.16</vendorAmountPaid>
</amountInvoiced>
<orderID>001AHF5423001</orderID>
<fiscalCycle>1997</fiscalCycle>
<orderLineNumber>1</orderLineNumber>
<numberOfCopies>1</numberOfCopies>
<vendorFinalPrice currency="$">35.16</vendorFinalPrice>
<orderlineKey>001AHF5423001_1997_1</orderlineKey>
<fundID>48020000</fundID>
<fundLibrary>BIOMEDICAL</fundLibrary>
<fiscalCycle>1997</fiscalCycle>
</invoiceLine>
<invoiceLine lineType="orderLine">
<lineNumber>2</lineNumber>
<amountInvoiced>
<vendorAmount currency="$">52.76</vendorAmount>
<vendorAmountPaid currency="$">52.76</vendorAmountPaid>
</amountInvoiced>
<orderID>001AHF5486001</orderID>
<fiscalCycle>1997</fiscalCycle>
<orderLineNumber>1</orderLineNumber>
<numberOfCopies>1</numberOfCopies>
<vendorFinalPrice currency="$">52.76</vendorFinalPrice>
<orderlineKey>001AHF5486001_1997_1</orderlineKey>
<fundID>48020000</fundID>
<fundLibrary>BIOMEDICAL</fundLibrary>
<fiscalCycle>1997</fiscalCycle>
</invoiceLine>
<invoiceLine lineType="orderLine">
<lineNumber>3</lineNumber>
<amountInvoiced>
<vendorAmount currency="$">70.40</vendorAmount>
<vendorAmountPaid currency="$">70.40</vendorAmountPaid>
</amountInvoiced>
<orderID>001AHF5492001</orderID>
<fiscalCycle>1997</fiscalCycle>
<orderLineNumber>1</orderLineNumber>
<numberOfCopies>1</numberOfCopies>
<vendorFinalPrice currency="$">70.40</vendorFinalPrice>
<orderlineKey>001AHF5492001_1997_1</orderlineKey>
<fundID>48020000</fundID>
<fundLibrary>BIOMEDICAL</fundLibrary>
<fiscalCycle>1997</fiscalCycle>
</invoiceLine>
<invoiceLine lineType="orderLine">
<lineNumber>4</lineNumber>
<amountInvoiced>
<vendorAmount currency="$">43.96</vendorAmount>
<vendorAmountPaid currency="$">43.96</vendorAmountPaid>
</amountInvoiced>
<orderID>001AHF5493001</orderID>
<fiscalCycle>1997</fiscalCycle>
<orderLineNumber>1</orderLineNumber>
<numberOfCopies>1</numberOfCopies>
<vendorFinalPrice currency="$">43.96</vendorFinalPrice>
<orderlineKey>001AHF5493001_1997_1</orderlineKey>
<fundID>48020000</fundID>
<fundLibrary>BIOMEDICAL</fundLibrary>
<fiscalCycle>1997</fiscalCycle>
</invoiceLine>
<invoiceLine lineType="orderLine">
<lineNumber>5</lineNumber>
<amountInvoiced>
<vendorAmount currency="$">61.60</vendorAmount>
<vendorAmountPaid currency="$">61.60</vendorAmountPaid>
</amountInvoiced>
<orderID>001AHF7077001</orderID>
<fiscalCycle>1997</fiscalCycle>
<orderLineNumber>1</orderLineNumber>
<numberOfCopies>1</numberOfCopies>
<vendorFinalPrice currency="$">61.60</vendorFinalPrice>
<orderlineKey>001AHF7077001_1997_1</orderlineKey>
<fundID>48020000</fundID>
<fundLibrary>BIOMEDICAL</fundLibrary>
<fiscalCycle>1997</fiscalCycle>
</invoiceLine>
<invoiceLine lineType="orderLine">
<lineNumber>6</lineNumber>
<amountInvoiced>
<vendorAmount currency="$">110.00</vendorAmount>
<vendorAmountPaid currency="$">110.00</vendorAmountPaid>
</amountInvoiced>
<orderID>001AHF7085001</orderID>
<fiscalCycle>1997</fiscalCycle>
<orderLineNumber>1</orderLineNumber>
<numberOfCopies>1</numberOfCopies>
<vendorFinalPrice currency="$">110.00</vendorFinalPrice>
<orderlineKey>001AHF7085001_1997_1</orderlineKey>
<fundID>48020000</fundID>
<fundLibrary>BIOMEDICAL</fundLibrary>
<fiscalCycle>1997</fiscalCycle>
</invoiceLine>
</invoice>
<invoice>
<library>VU-PROCESS</library>
<invoiceID>106543</invoiceID>
<vendorID>7828</vendorID>
<invoiceControlNumber> 3</invoiceControlNumber>
<createdInFiscalCycle>1997</createdInFiscalCycle>
<total>
<vendorAmount currency="$">235.80</vendorAmount>
<vendorAmountPaid currency="$">235.80</vendorAmountPaid>
</total>
<dateCreated>1996-08-14</dateCreated>
<dateModified>1996-08-20</dateModified>
<dateInvoiced>1996-06-14</dateInvoiced>
<extendedInfo>
<entry name="Note">mew</entry>
</extendedInfo>
<fundSummary>
<fund>
<fundID>23022300</fundID>
<fiscalCycle>1997</fiscalCycle>
<accountNumber>1532200000,74500</accountNumber>
<amountInvoiced currency="$">0.00</amountInvoiced>
<amountPaid currency="$">102.53</amountPaid>
</fund>
<fund>
<fundID>23023700</fundID>
<fiscalCycle>1997</fiscalCycle>
<accountNumber>1534310000,74500</accountNumber>
<amountInvoiced currency="$">0.00</amountInvoiced>
<amountPaid currency="$">27.27</amountPaid>
</fund>
<fund>
<fundID>23024400</fundID>
<fiscalCycle>1997</fiscalCycle>
<accountNumber>1532200000,74500</accountNumber>
<amountInvoiced currency="$">0.00</amountInvoiced>
<amountPaid currency="$">70.55</amountPaid>
</fund>
<fund>
<fundID>23028800</fundID>
<fiscalCycle>1997</fiscalCycle>
<accountNumber>1532200000,74500</accountNumber>
<amountInvoiced currency="$">0.00</amountInvoiced>
<amountPaid currency="$">35.45</amountPaid>
</fund>
</fundSummary>
<numberOfLines>9</numberOfLines>
<numberOfLinesPaid>9</numberOfLinesPaid>
<numberOfCopies>8</numberOfCopies>
<numberOfCopiesPaid>8</numberOfCopiesPaid>
<invoiceLine lineType="orderLine">
<lineNumber>1</lineNumber>
<amountInvoiced>
<vendorAmount currency="$">30.00</vendorAmount>
<vendorAmountPaid currency="$">30.00</vendorAmountPaid>
</amountInvoiced>
<orderID>001AHF3988001</orderID>
<fiscalCycle>1997</fiscalCycle>
<orderLineNumber>1</orderLineNumber>
<numberOfCopies>1</numberOfCopies>
<vendorFinalPrice currency="$">30.00</vendorFinalPrice>
<orderlineKey>001AHF3988001_1997_1</orderlineKey>
<fundID>23024400</fundID>
<fundLibrary>VU-PROCESS</fundLibrary>
<fiscalCycle>1997</fiscalCycle>
</invoiceLine>
<invoiceLine lineType="orderLine">
<lineNumber>2</lineNumber>
<amountInvoiced>
<vendorAmount currency="$">18.95</vendorAmount>
<vendorAmountPaid currency="$">18.95</vendorAmountPaid>
</amountInvoiced>
<orderID>001AHE9316001</orderID>
<fiscalCycle>1997</fiscalCycle>
<orderLineNumber>1</orderLineNumber>
<numberOfCopies>1</numberOfCopies>
<vendorFinalPrice currency="$">18.95</vendorFinalPrice>
<orderlineKey>001AHE9316001_1997_1</orderlineKey>
<fundID>23028800</fundID>
<fundLibrary>VU-PROCESS</fundLibrary>
<fiscalCycle>1997</fiscalCycle>
</invoiceLine>
<invoiceLine lineType="orderLine">
<lineNumber>3</lineNumber>
<amountInvoiced>
<vendorAmount currency="$">17.00</vendorAmount>
<vendorAmountPaid currency="$">17.00</vendorAmountPaid>
</amountInvoiced>
<orderID>001AHE5275001</orderID>
<fiscalCycle>1997</fiscalCycle>
<orderLineNumber>1</orderLineNumber>
<numberOfCopies>1</numberOfCopies>
<vendorFinalPrice currency="$">17.00</vendorFinalPrice>
<orderlineKey>001AHE5275001_1997_1</orderlineKey>
<fundID>23022300</fundID>
<fundLibrary>VU-PROCESS</fundLibrary>
<fiscalCycle>1997</fiscalCycle>
</invoiceLine>
<invoiceLine lineType="orderLine">
<lineNumber>4</lineNumber>
<amountInvoiced>
<vendorAmount currency="$">26.50</vendorAmount>
<vendorAmountPaid currency="$">26.50</vendorAmountPaid>
</amountInvoiced>
<orderID>001AHF1062001</orderID>
<fiscalCycle>1997</fiscalCycle>
<orderLineNumber>1</orderLineNumber>
<numberOfCopies>1</numberOfCopies>
<vendorFinalPrice currency="$">26.50</vendorFinalPrice>
<orderlineKey>001AHF1062001_1997_1</orderlineKey>
<fundID>23023700</fundID>
<fundLibrary>VU-PROCESS</fundLibrary>
<fiscalCycle>1997</fiscalCycle>
</invoiceLine>
<invoiceLine lineType="orderLine">
<lineNumber>5</lineNumber>
<amountInvoiced>
<vendorAmount currency="$">23.25</vendorAmount>
<vendorAmountPaid currency="$">23.25</vendorAmountPaid>
</amountInvoiced>
<orderID>001AHE2367001</orderID>
<fiscalCycle>1997</fiscalCycle>
<orderLineNumber>1</orderLineNumber>
<numberOfCopies>1</numberOfCopies>
<vendorFinalPrice currency="$">23.25</vendorFinalPrice>
<orderlineKey>001AHE2367001_1997_1</orderlineKey>
<fundID>23022300</fundID>
<fundLibrary>VU-PROCESS</fundLibrary>
<fiscalCycle>1997</fiscalCycle>
</invoiceLine>
<invoiceLine lineType="orderLine">
<lineNumber>6</lineNumber>
<amountInvoiced>
<vendorAmount currency="$">39.00</vendorAmount>
<vendorAmountPaid currency="$">39.00</vendorAmountPaid>
</amountInvoiced>
<orderID>002AHC0935001</orderID>
<fiscalCycle>1997</fiscalCycle>
<orderLineNumber>1</orderLineNumber>
<numberOfCopies>1</numberOfCopies>
<vendorFinalPrice currency="$">39.00</vendorFinalPrice>
<orderlineKey>002AHC0935001_1997_1</orderlineKey>
<fundID>23024400</fundID>
<fundLibrary>VU-PROCESS</fundLibrary>
<fiscalCycle>1997</fiscalCycle>
</invoiceLine>
<invoiceLine lineType="orderLine">
<lineNumber>7</lineNumber>
<amountInvoiced>
<vendorAmount currency="$">14.95</vendorAmount>
<vendorAmountPaid currency="$">14.95</vendorAmountPaid>
</amountInvoiced>
<orderID>001AHE9312001</orderID>
<fiscalCycle>1997</fiscalCycle>
<orderLineNumber>1</orderLineNumber>
<numberOfCopies>1</numberOfCopies>
<vendorFinalPrice currency="$">14.95</vendorFinalPrice>
<orderlineKey>001AHE9312001_1997_1</orderlineKey>
<fundID>23028800</fundID>
<fundLibrary>VU-PROCESS</fundLibrary>
<fiscalCycle>1997</fiscalCycle>
</invoiceLine>
<invoiceLine lineType="orderLine">
<lineNumber>8</lineNumber>
<amountInvoiced>
<vendorAmount currency="$">59.95</vendorAmount>
<vendorAmountPaid currency="$">59.95</vendorAmountPaid>
</amountInvoiced>
<orderID>001AHF2201001</orderID>
<fiscalCycle>1997</fiscalCycle>
<orderLineNumber>1</orderLineNumber>
<numberOfCopies>1</numberOfCopies>
<vendorFinalPrice currency="$">59.95</vendorFinalPrice>
<orderlineKey>001AHF2201001_1997_1</orderlineKey>
<fundID>23022300</fundID>
<fundLibrary>VU-PROCESS</fundLibrary>
<fiscalCycle>1997</fiscalCycle>
</invoiceLine>
<invoiceLine lineType="proratedByLine">
<lineNumber>SHIPPING</lineNumber>
<amountInvoiced>
<vendorAmount currency="$">6.20</vendorAmount>
<vendorAmountPaid currency="$">6.20</vendorAmountPaid>
</amountInvoiced>
</invoiceLine>
</invoice>
<invoice>
<library>VU-PROCESS</library>
<invoiceID>106551</invoiceID>
<vendorID>7828</vendorID>
<invoiceControlNumber> 5</invoiceControlNumber>
<createdInFiscalCycle>1997</createdInFiscalCycle>
<total>
<vendorAmount currency="$">524.27</vendorAmount>
<vendorAmountPaid currency="$">524.27</vendorAmountPaid>
</total>
<dateCreated>1996-08-14</dateCreated>
<dateModified>1996-08-20</dateModified>
<dateInvoiced>1996-06-14</dateInvoiced>
<extendedInfo>
<entry name="Note">mew</entry>
</extendedInfo>
<fundSummary>
<fund>
<fundID>46024600</fundID>
<fiscalCycle>1997</fiscalCycle>
<accountNumber>1532200000,74500</accountNumber>
<amountInvoiced currency="$">0.00</amountInvoiced>
<amountPaid currency="$">524.27</amountPaid>
</fund>
</fundSummary>
<numberOfLines>7</numberOfLines>
<numberOfLinesPaid>7</numberOfLinesPaid>
<numberOfCopies>6</numberOfCopies>
<numberOfCopiesPaid>6</numberOfCopiesPaid>
<invoiceLine lineType="orderLine">
<lineNumber>1</lineNumber>
<amountInvoiced>
<vendorAmount currency="$">118.75</vendorAmount>
<vendorAmountPaid currency="$">118.75</vendorAmountPaid>
</amountInvoiced>
<orderID>001AHF2309001</orderID>
<fiscalCycle>1997</fiscalCycle>
<orderLineNumber>1</orderLineNumber>
<numberOfCopies>1</numberOfCopies>
<vendorFinalPrice currency="$">118.75</vendorFinalPrice>
<orderlineKey>001AHF2309001_1997_1</orderlineKey>
<fundID>46024600</fundID>
<fundLibrary>VU-PROCESS</fundLibrary>
<fiscalCycle>1997</fiscalCycle>
</invoiceLine>
<invoiceLine lineType="orderLine">
<lineNumber>2</lineNumber>
<amountInvoiced>
<vendorAmount currency="$">80.75</vendorAmount>
<vendorAmountPaid currency="$">80.75</vendorAmountPaid>
</amountInvoiced>
<orderID>001AHF2311001</orderID>
<fiscalCycle>1997</fiscalCycle>
<orderLineNumber>1</orderLineNumber>
<numberOfCopies>1</numberOfCopies>
<vendorFinalPrice currency="$">80.75</vendorFinalPrice>
<orderlineKey>001AHF2311001_1997_1</orderlineKey>
<fundID>46024600</fundID>
<fundLibrary>VU-PROCESS</fundLibrary>
<fiscalCycle>1997</fiscalCycle>
</invoiceLine>
<invoiceLine lineType="orderLine">
<lineNumber>3</lineNumber>
<amountInvoiced>
<vendorAmount currency="$">85.45</vendorAmount>
<vendorAmountPaid currency="$">85.45</vendorAmountPaid>
</amountInvoiced>
<orderID>001AHF2369001</orderID>
<fiscalCycle>1997</fiscalCycle>
<orderLineNumber>1</orderLineNumber>
<numberOfCopies>1</numberOfCopies>
<vendorFinalPrice currency="$">85.45</vendorFinalPrice>
<orderlineKey>001AHF2369001_1997_1</orderlineKey>
<fundID>46024600</fundID>
<fundLibrary>VU-PROCESS</fundLibrary>
<fiscalCycle>1997</fiscalCycle>
</invoiceLine>
<invoiceLine lineType="orderLine">
<lineNumber>4</lineNumber>
<amountInvoiced>
<vendorAmount currency="$">85.45</vendorAmount>
<vendorAmountPaid currency="$">85.45</vendorAmountPaid>
</amountInvoiced>
<orderID>001AHF2313001</orderID>
<fiscalCycle>1997</fiscalCycle>
<orderLineNumber>1</orderLineNumber>
<numberOfCopies>1</numberOfCopies>
<vendorFinalPrice currency="$">85.45</vendorFinalPrice>
<orderlineKey>001AHF2313001_1997_1</orderlineKey>
<fundID>46024600</fundID>
<fundLibrary>VU-PROCESS</fundLibrary>
<fiscalCycle>1997</fiscalCycle>
</invoiceLine>
<invoiceLine lineType="orderLine">
<lineNumber>5</lineNumber>
<amountInvoiced>
<vendorAmount currency="$">94.95</vendorAmount>
<vendorAmountPaid currency="$">94.95</vendorAmountPaid>
</amountInvoiced>
<orderID>001AHF2325001</orderID>
<fiscalCycle>1997</fiscalCycle>
<orderLineNumber>1</orderLineNumber>
<numberOfCopies>1</numberOfCopies>
<vendorFinalPrice currency="$">94.95</vendorFinalPrice>
<orderlineKey>001AHF2325001_1997_1</orderlineKey>
<fundID>46024600</fundID>
<fundLibrary>VU-PROCESS</fundLibrary>
<fiscalCycle>1997</fiscalCycle>
</invoiceLine>
<invoiceLine lineType="orderLine">
<lineNumber>6</lineNumber>
<amountInvoiced>
<vendorAmount currency="$">45.13</vendorAmount>
<vendorAmountPaid currency="$">45.13</vendorAmountPaid>
</amountInvoiced>
<orderID>001AHF2368001</orderID>
<fiscalCycle>1997</fiscalCycle>
<orderLineNumber>1</orderLineNumber>
<numberOfCopies>1</numberOfCopies>
<vendorFinalPrice currency="$">45.13</vendorFinalPrice>
<orderlineKey>001AHF2368001_1997_1</orderlineKey>
<fundID>46024600</fundID>
<fundLibrary>VU-PROCESS</fundLibrary>
<fiscalCycle>1997</fiscalCycle>
</invoiceLine>
<invoiceLine lineType="proratedByLine">
<lineNumber>SHIPPING</lineNumber>
<amountInvoiced>
<vendorAmount currency="$">13.79</vendorAmount>
<vendorAmountPaid currency="$">13.79</vendorAmountPaid>
</amountInvoiced>
</invoiceLine>
</invoice>
</report>
答案 0 :(得分:0)
XMLReader用于逐个读取大型XML文档。这意味着您无法修改原始内容 - 它永远不会作为一个整体提供。缺少的组件是XMLWriter。通过invoice
读取源XML invoice
并创建该文件的修改副本。此外,这种方法是可重复的,如果出现问题,不会破坏原始数据。
XMLReader::expand()
从XMLReader创建DOM结构。修改节点并使用XMLWriter将它们写入目标文档。
为了让我更容易,我在FluentDOM(我自己的PHP XML库)中为XMLWriter添加了一个collapse()
方法。
使用FluentDOM代码可能如下所示:
// load the source into a reader
$reader = new \FluentDOM\XMLReader();
$reader->open(__DIR__.'/test.xml');
// create a writer instance for the target file
$writer = new \FluentDOM\XMLWriter();
$writer->openUri(__DIR__.'/test-output.xml');
$writer->setIndent(2);
$writer->startDocument();
$writer->startElement('report');
// iterate the invoice elements
/** @var \FluentDOM\DOM\Element $invoiceNode */
foreach (new FluentDOM\XMLReader\SiblingIterator($reader, 'invoice') as $invoiceNode) {
// fetch the proratedByLine invoiceLine as target node
/** @var \FluentDOM\DOM\Element|NULL $shippingNode */
$shippingNode = $invoiceNode->evaluate('invoiceLine[@lineType = "proratedByLine"]')[0];
// if here is a shipping line, check and modify
if ($shippingNode) {
echo 'InvoiceID: '.$invoiceNode->evaluate('string(invoiceID)'), PHP_EOL;
// collect the fundSummary by fundId
$currentTotals = [];
/** @var \FluentDOM\DOM\Element $fund */
foreach ($invoiceNode->evaluate('fundSummary/fund') as $fund) {
$totals[$fund->evaluate('string(fundID)')] = $fund->evaluate('number(amountPaid)');
}
// iterate all orderLine values and sum them up grouped by fund ID
$vendorPaid = [];
/** @var \FluentDOM\DOM\Element $line */
foreach ($invoiceNode->evaluate('invoiceLine[@lineType = "orderLine"]') as $line) {
$fundID = $line->evaluate('string(fundID)');
if (!isset($lines[$fundID])) {
$vendorPaid[$fundID] = 0;
}
$vendorPaid[$fundID] += $line->evaluate('number(amountInvoiced/vendorAmountPaid)');
}
// build a list with all fundIDs
$fundIDs = array_merge(array_keys($currentTotals), array_keys($vendorPaid));
// iterate over them
foreach ($fundIDs as $fundID) {
// calculate the new value
$totalValue = $currentTotals[$fundID] ?? 0.0;
$vendorValue = $vendorPaid[$fundID] ?? 0.0;
$value = number_format($totalValue - $vendorValue, 2);
// modify the $targetNode or $invoiceNode as needed
// for example add the values as a new element to the $shippingNode
$entry = $shippingNode->appendElement('calculated-entry');
$entry->appendElement('fundID', $fundID);
$entry->appendElement('vendorFinalPrice', $value, ['currency'=> '$']);
}
}
// collapse/write the invoice element into the target file
$writer->collapse($invoiceNode);
}
$writer->endElement();
$writer->endDocument();