[英]PHP to reformat XML steps needed
我想自己編寫代碼,但我需要有人告訴我我在這里處理什么並布置基本步驟,而不是實際代碼。 現在我的 PHP 通過 http get web 調用獲取文件內容。 返回給我的數據是XML節點結構。 醫療索賠返回,因此可能有一個索賠或 200 個索賠返回,但所有的結構都是明智的,它們只是重復。 我需要獲取 CLAIM 主元素中的每個元素名稱,並讓這些名稱水平打印,由我在第二個示例 output 中使用的點划定。 我只需要它水平列出這些名稱一次,而不是重復。 然后我需要讓元素中間的實際數據也用我的點划線水平顯示。 因此,如果返回了 100 個索賠,我需要這些數據繼續以我的點划線水平顯示。
<CLAIM_LIST>
<CLAIM>
<fund_code>TTG-PMA N351</fund_code>
<fund_name>TTG</fund_name>
<ProviderTIN>444555666</ProviderTIN>
</CLAIM>
<CLAIM>
<fund_code>XXX-PMA N444</fund_code>
<fund_name>ILWU</fund_name>
<ProviderTIN>888777666</ProviderTIN>
</CLAIM>
<CLAIM>
</CLAIM_LIST>
TURN the above into the below. I know how to do the dot delineation, and the column_names and data name elements.
<column_names>
fund_code·fund_name·ProviderTIN
</column_names>
<data>
TTG-PMA N351·TTG·44555666·XXX-PMA N444·ILWU·888777666
</data>
我做到了,其實我自己也很驚訝。 $file 是我想要修改的整個結果。 這給了我想要的水平 output。 現在唯一的問題是獲得行數。 有什么建議么? 涉及一些數學的東西,比如把我得到的列數與總行 output 上有多少個點划定的位置進行比較,然后除以?
要刪除列名,請將點划線放入並返回多少列的計數
$xml = simplexml_load_string($file);
foreach($xml->children()->children() as $child){
$claimsNames .= $child->getName() . "·" . "";
$col_count++;
}
Then to strip out the data in all the elements and also put dot delineation in
$claimsData = trim(preg_replace('/<[^>]*>/', ' ', $file));
$claimsData = str_replace( ' ', '·', $claimsData );
我的最終代碼:
$file = file_get_contents($remote_url, false, $context); // Open the
file using the HTTP headers set above
$start_time = microtime(true);
$col_count = 0;
$row_count = 0;
$xml = simplexml_load_string($file);
// THE LOOP! To strip column names out of XML elements and display how
many columns
foreach($xml->children()->children() as $child)
{
$claimsNames .= $child->getName() . "·" . "";
$col_count++;
}
$claimsData = trim(preg_replace('/<[^>]*>/', ' ', $file));
$claimsData = str_replace( ' ', '·', $claimsData );
$row_count1 = count(explode('·', $claimsData)); // how many total dots
starting at 1
$ColPlusOne = ($col_count + 1); //28 plus 1 = 29
$row_count2 = ($row_count1 / $ColPlusOne); // divide above by
number of columns and round, to give total number of rows
$row_count3 = ceil($row_count2*1)/1; // round return up
if ($col_count == "28") { //checking for no record
$col_count = $col_count;
$row_count3 = $row_count3;
} else {
$col_count = "0";
$row_count3 = "0";
}
$time = round( (microtime(true) - $start_time), 4);
?>
<response>
<time><?=$time?></time>
<cols><?=$col_count?></cols>
<rows><?=$row_count3?></rows>
<column_names>
<?=$claimsNames?>
</column_names>
<data>
<?=$claimsData?>
</data>
</response>
It gives output like this:
<response>
<time>0.0029</time>
<cols>28</cols>
<rows>83</rows>
<column_names>
fund_code·fund_name·ProviderTIN·provider_name·claim_num·status·dos·dos_end·ProcessDate·patient_id·patient_dob·patient_name·patient_lastname·patient_firstname·patient_middlename·patient_relationship·Payee·AmountBilled·AmountCovered·AmountPaid·AmountCopay·Discount·Deductible·PatientAmount·dup·Source·ClaimSource·OriginalClaimNumber·
</column_names>
<data>
TTG-PMA N351·TTG·111222999··20200312-209·Issued·20200303·20200303·20200312·0000037725·19510915·VAN HALEN EDDIE·VAN HALEN·EDDIE··Participant·Provider·8127.00·2888.80·2888.80·0.00·5238.20·0.00·0.00··AMBICAB·SG·20200312-209··TTG-PMA N351·TTG·111222999··20200318-1361·Issued·20200303·20200303·20200318·0000037725·19510915·VAN HALEN EDDIE·VAN HALEN·EDDIE··Participant·Provider·26.00·9.99·9.99·0.00·16.01·0.00·0.00··AMBICAB·SG·20200318-1361··TTG-PMA N351·TTG·111222999··20200318-1362·Issued·20200303·20200303·20200318·0000037725·19510915·VAN HALEN EDDIE·VAN HALEN·EDDIE··Participant·Provider·17.00·10.31·10.31·0.00·6.69·0.00·0.00··AMBICAB·SG·20200318-1362··TTG-PMA N351·TTG·252363454··20200407-1405·Issued·20200303·20200303·20200407·0000037725·19510915·VAN HALEN EDDIE·VAN HALEN·EDDIE··Participant·Provider·765.00·180.57·180.57·0.00·584.43·0.00·0.00··AMBICAB·SG·20200407-1405··TTG-PMA N351·TTG·472728752··20191119-3554·Issued·20191021·20191021·20191120·0000037725·19510915·VAN HALEN
我非常感謝您花時間在這里 Jack 並編寫了您所做的代碼。 我有很多東西要從你的代碼中學習。 我永遠不會知道 RegEx。 我以前從未使用過“DOM”。 我的代碼可能是,好吧,它是一個 hack 工作和數學,我花了一段時間來測試 30 個不同的索賠返回,但它總是給我正確的行數。 這適用於 Cisco IVR,因此我需要將 XML 保持為 XML,但格式與它一樣,以便 Cisco 可以為其處理維護字符串描述計數。 任何一個都不會出現在終端屏幕上,因為它的 100% 機器對機器,因此 XML 格式一直是。 列數和行數在 IVR 世界中非常重要。
首先要做的事情是:您正在處理 xml,而且是一個復雜的。 一件事不是一個好主意是使用正則表達式處理 xml(或 html,就此而言)。 搜索一下,你會發現這是一個幾乎普遍的共識。
最適合使用 xml 的工具是 xpath 和 xquery。 不幸的是,php 中的 xpath 支持很糟糕,因此要獲得您所期望的 output 將涉及很多心理操。
話雖如此,既然您要求在 php 中執行此操作,因此 php 中的答案如下:
$string = <<<XML
[your xml snippet above]
XML;
//loading boilerplate
$claimsdoc = new DOMDocument();
$claimsdoc->loadXML($string);
$claimsdoc_xpath = new DOMXPath($claimsdoc);
$claims = $claimsdoc_xpath->evaluate('count(//CLAIM)'); //get the number of CLAIMs
$tags = $claimsdoc_xpath->evaluate('count(//CLAIM[1]//*)');//get the number of tags per CLAIM
//get the column names and create the xml output
$cols = $claimsdoc_xpath->evaluate(".//CLAIM[1]//*");
$colnames = htmlspecialchars("<column_names>", ENT_QUOTES) . "\n<br>";
for ($x = 0; $x < $tags; $x++) {
$result = $cols[$x];
$colnames .= "$result->tagName";
if ($x < $tags-1)
$colnames.=" * ";
}
$colnames .= "\n<br>" . htmlspecialchars("</column_names>", ENT_QUOTES);
//get the claim data and create the xml output
$data = htmlspecialchars("<data>", ENT_QUOTES) . "\n<br>";
for ($x = 1; $x <= $claims; $x++) {
$result = $claimsdoc_xpath->evaluate("concat(.//CLAIM[$x]//fund_code/text(),' * ',.//CLAIM[$x]//fund_name,' * ',.//CLAIM[$x]//ProviderTIN)");
$data .=$result;
if ($x < $claims)
$data .=" * ";
}
$data .= "\n<br>" . htmlspecialchars("</data>", ENT_QUOTES);
echo $colnames;
echo "\n<br>";
echo $data;
Output:
<column_names>
fund_code * fund_name * ProviderTIN
</column_names>
<data>
TTG-PMA N351 * TTG * 444555666 * XXX-PMA N444 * ILWU * 888777666
</data>
正如我在開頭提到的那樣,如果您的數據集足夠大並且您必須經常這樣做,那么學習 xpath/xquery 並使用 xml 數據庫(如 BaseX)可能是值得的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.