我正在使用API返回的XML文档。 XML返回一个产品列表,其中包含每个项目的属性,如库存,项目编号,名称,价格等。
我可以遍历所有XML表,创建所有产品的列表,并显示相应的字段。问题是,我需要能够定义某些产品及其变量。
如何从XML产品创建类或数组,但仅限于某些类?例如,可能有40件产品退回,但我可能只需要其中的3件。数组或类必须包含产品的所有相关信息。
Here's a link to an example of the raw XML returned by the API
XML的一个例子是
<diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1">
<NewDataSet xmlns="">
<Table diffgr:id="Table1" msdata:rowOrder="0">
<ChargeDescID>14249</ChargeDescID>
<sChgDesc>Cleaning Deposit</sChgDesc>
<dcPrice>0.0000</dcPrice>
<dcTax1Rate>0</dcTax1Rate>
<dcTax2Rate>0</dcTax2Rate>
<dcInStock>0.0000</dcInStock>
</Table>
<Table diffgr:id="Table2" msdata:rowOrder="1">
<ChargeDescID>14251</ChargeDescID>
<sChgDesc>Utility Knife</sChgDesc>
<dcPrice>2.9900</dcPrice>
<dcTax1Rate>9</dcTax1Rate>
<dcTax2Rate>0</dcTax2Rate>
<dcInStock>0.0000</dcInStock>
</Table>
</NewDataSet>
因此,使用上面代码中的第二个产品作为示例,我想要一个PHP函数,它将创建一个类或这样的数组:
$utility_knife (
"ChargeDescID" => "14251",
"dcPrice" => "2.99",
"dcTax1Rate" => "9",
"dcTax2Rate" => "0",
"dcInStock" => "0",
)
如何提取特定的diffgr表并将它们格式化为命名数组或类,忽略我不需要的表?如何在忽略其他表的同时获取表的内容?
编辑以包含我尝试过的内容:
我已经能够使用loadXML()和DOMXPath将它们拉入数组,如下所示:
$dom = new DOMDocument;
$dom->loadXML($result);
$xpath = new DOMXPath($dom);
$el = $xpath->query('//Table');
#loop through results
foreach($el as $units) {
$ChargeDescID = $xpath->query('ChargeDescID', $units)->item(0)->nodeValue;
$sChgDesc = $xpath->query('sChgDesc', $units)->item(0)->nodeValue;
$dcPrice = $xpath->query('dcPrice', $units)->item(0)->nodeValue;
$dcTax1Rate = $xpath->query('dcTax1Rate', $units)->item(0)->nodeValue;
$dcTax2Rate = $xpath->query('dcTax2Rate', $units)->item(0)->nodeValue;
$dcInStock = $xpath->query('dcInStock', $units)->item(0)->nodeValue;
#create oragnized array for results
$iterate_list = array("ChargeDescID"=>$ChargeDescID,"sChgDesc"=>$sChgDesc, "dcPrice"=>$dcPrice, "dcTax1Rate"=>$dcTax1Rate, "dcTax2Rate"=>$dcTax2Rate, "dcInStock"=>$dcInStock);
#create/append array of array
$results_list[] = $iterate_list;
}
所以现在我有一个名为$ results_list的数组,子数组以$ key / $ value对组织,但数组本身没有命名。我可以这样有条理地打印出结果:
foreach($results_list as $key => $value) {
echo
"Charge Description ID: " . $results_list[$key]["ChargeDescID"] . "<br>" .
"Item Description: " . $results_list[$key]["sChgDesc"] . "<br>" .
"Item Price: " . $results_list[$key]["dcPrice"] . "<br>" .
"Tax rate 1: " . $results_list[$key]["dcTax1Rate"] . "<br>" .
"tax rate 2: " . $results_list[$key]["dcTax2Rate"] . "<br>" .
"In Stock: " . $results_list[$key]["dcInStock"] . "<br>"
;
}
编辑:我在下面提出的解决方案有效。我目前正在使用它,但我愿意接受更优雅的解决方案。优选地,直接选择节点而不需要条件逻辑。你提出了一些可行的方法。我正在等待他的澄清。
问题在于我无法弄清楚如何获得特定产品。我知道我可以使用数组索引,但索引可能会从一个拉到下一个拉。我想我需要某种类似于:
的功能foreach($results_list as $key => $value){
if ( $results_list[$key]["sChgDesc"] == "Utility Knife" ) {
$utility_knife = array(
"sChgDesc" => $results_list[$key]["sChgDesc"],
"dcPrice" => $results_list[$key]["dcPrice"],
"dcTax1Rate" => $results_list[$key]["dcTax1Rate"],
"dcInStock" => $results_list[$key]["dcInStock"],
);
然后在数组中写出我需要的每个产品的if语句。那是对的吗?
我已经尝试过多次这样做,因为我开始迷惑自己。我不确定是否可以在其中一个子数组值上调用if语句,然后如果值存在则循环返回该特定子数组中的其余值。
需要挑选的标准是我必须能够确定我选择的产品。所以它可能依赖于ChargeDescID或sChgDesc,但实际上并不依赖于其他任何东西。然后我需要确保填充其他相关字段。
答案 0 :(得分:2)
您已经在使用XPath,但它可以做更多事情。 DOMXpath :: query()也是有限的。使用DOMXpath :: evaluate() - 它可以返回标量值。
例如:
$ChargeDescID = $xpath->query('ChargeDescID', $units)->item(0)->nodeValue;
可以重构为:
$ChargeDescID = $xpath->evaluate('string(ChargeDescID)', $units);
XPath可以包含复杂的条件。假设您要使用Table
属性diffgr:id
获取Table1
个元素节点:
$xpath->registerNamespace('diffgr', 'urn:schemas-microsoft-com:xml-diffgram-v1');
$el = $xpath->evaluate('//Table[@diffgr:id="Table1"]');
XPath没有默认命名空间,因此如果要在不同的命名空间中寻址节点,则需要为空命名空间(xmlns=""
)注册一个前缀。这可以是与文档中相同的前缀或不同的前缀。
另一方面,您可以按名称或更通用的方式获取节点。 *
表示任何元素节点。
$dom = new DOMDocument();
$dom->loadXml($xml);
$xpath = new DOMXPath($dom);
$xpath->registerNamespace('diffgr', 'urn:schemas-microsoft-com:xml-diffgram-v1');
$el = $xpath->evaluate('//Table[@diffgr:id="Table1"]');
$results_list = [];
foreach ($el as $units) {
$iterate_list = [];
foreach ($xpath->evaluate('*', $units) as $valueNode) {
$iterate_list[$valueNode->localName] = $valueNode->nodeValue;
}
$results_list[] = $iterate_list;
}
var_dump($results_list);
输出:
array(1) {
[0]=>
array(6) {
["ChargeDescID"]=>
string(5) "14249"
["sChgDesc"]=>
string(16) "Cleaning Deposit"
["dcPrice"]=>
string(6) "0.0000"
["dcTax1Rate"]=>
string(1) "0"
["dcTax2Rate"]=>
string(1) "0"
["dcInStock"]=>
string(6) "0.0000"
}
}
答案 1 :(得分:-1)
你已经尝试过这个:
$xml = simplexml_load_file('file_xml.xml');
print '<pre>';
print_r($xml);
print_r仅用于调试