簡體   English   中英

PHP 重新格式化 XML 需要步驟

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM