簡體   English   中英

從asXML()獲取XML標簽

[英]Get XML tags from asXML()

我正在解析XML文檔,並使用asXML()獲取嵌套標簽的值。 這可以正常工作,但是我想將這些數據移入一個MySQL數據庫,該數據庫的列與文件的標簽匹配。 那么從本質上來說,我如何獲得asXML()從中提取文本的標簽?

這樣,我最終可以做類似的事情: INSERT INTO db.table (TheXMLTag) VALUES ('XMLTagText');

到目前為止,這是我的代碼:

$xml = simplexml_load_file($target_file) or die ("Error: Cannot create object");

foreach ($xml->Message->SettlementReport->SettlementData as $main ){
    $value = $main->asXML();
    echo '<pre>'; echo $value; echo '</pre>';
}

foreach ($xml->Message->SettlementReport->Order as $main ){
    $value = $main->asXML();
    echo '<pre>'; echo $value; echo '</pre>';
}

這是我的文件看起來像一個想法(因此,從本質上講,我如何在[SettlementData],[0],[Fulfillment],[Item]等中獲取標簽?): 在此處輸入圖片說明

我嘗試過使用SimpleXML但是它會跳過文本數據。 但是,使用Document Object Model擴展名是可行的。

這將返回一個數組,其中每個元素都是具有2個鍵的數組: tagtext ,以遍歷樹的順序返回。

<?php
// recursive, pass by reference (spare memory ? meh...)
// can skip non tag elements (removes lots of empty elements)
function tagData(&$node, $skipNonTag=false) {

   // get function name, allows to rename function without too much work
   $self = __FUNCTION__;

   // init
   $out      = array();
   $innerXML = '';

   // get document
   $doc = $node->nodeName == '#document'
      ? $node
      : $node->ownerDocument;

   // current tag
   // we use a reference to innerXML to fill it later to keep the tree order
   // without ref, this would go after the loop, children would appear first
   // not really important but we never know
   if(!(mb_substr($node->nodeName,0,1) == '#' && $skipNonTag)) {
      $out[] = array(
         'tag'  => $node->nodeName,
         'text' => &$innerXML,
      );
   }

   // build current innerXML and process children
   // check for children
   if($node->hasChildNodes()) {

      // process children
      foreach($node->childNodes as $child) {

         // build current innerXML
         $innerXML .= $doc->saveXML($child);

         // repeat process with children
         $out = array_merge($out, $self($child, $skipNonTag));
      }
   }

   // return current + children
   return $out;
}

$xml = new DOMDocument();
$xml->load($target_file) or die ("Error: Cannot load xml");
$tags = tagData($xml, true);
//print_r($tags);
?>

我想將這些數據移入MySQL數據庫,其列與文件的標簽匹配。

您的問題是兩折。

問題的第一部分是對數據庫結構進行自省 即,獲取所有表名並獲取這些表的列名。 大多數現代數據庫都提供此功能,MySQL也是如此。 在MySQL中,這些是INFORMATION_SCHEMA表 您可以像查詢普通數據庫表一樣查詢它們。 我通常建議在PHP中使用PDOmysqli自然也可以完美地完成這項工作。

第二部分是解析XML數據並將其數據映射到數據庫表中(您在問題中使用SimpleXMLElement ,所以我專門與它有關)。 為此,您首先需要了解如何將XML中的數據映射到數據庫。 XML文件不像關系數據庫表那樣具有2D結構,但是具有樹結構。

例如(如果我沒看錯的話),您將Message->SettlementReport->SettlementData標識為第一個“表” 對於該特定示例,這很容易,因為<SettlementData>僅具有可以表示列名稱(元素名稱)和值(文本內容)的子元素。 為此,這很容易:

header('Content-Type: text/plain; charset=utf-8');
$table = $xml->Message->SettlementReport->SettlementData;
foreach ($table as $name => $value ) {
    echo $name, ': ', $value, "\n";
}

如您所見,在foreach子句中指定分配將為您提供帶有SimpleXMLElement的元素名稱。 或者, SimpleXMLElement::getName()方法執行相同的操作(只是一個示例,僅使用稍微不同的代碼即可執行相同的操作):

header('Content-Type: text/plain; charset=utf-8');
$table = $xml->Message->SettlementReport->SettlementData;
foreach ($table as $value) {
    $name = $value->getName();
    echo $name, ': ', $value, "\n";
}

在這種情況下,您將受益於以下事實:通過$xml->...->SettlementData訪問的SimpleXMLElementforeach中提供的迭代器遍歷所有子元素。

這里更通用的概念是Xpath。 因此,請允許我向您展示第三個示例,該示例再次執行類似的輸出:

header('Content-Type: text/plain; charset=utf-8');
$rows = $xml->xpath('/*/Message/SettlementReport/SettlementData');
foreach ($rows as $row) {
    foreach ($row as $column) {
        $name  = $column->getName();
        $value = (string) $column;
        echo $name, ': ', $value, "\n";
    }
}

但是,如前所述,將樹結構(N-Depth)映射到2D結構(數據庫表)現在可能總是很簡單。

如果您正在尋找可能的結果(通常是數據丟失或數據重復),則在前面的問答中將給出一個更復雜的PHP示例:

請注意:事實上,此類映射本身可能很復雜,因此問題和答案都繼承自該復雜性。 首先,這意味着這些內容可能不容易閱讀,而且-也許更為突出-可能不適用於您的問題。 這些只是為了擴大您的視野並提供某些情況下的示例。

希望對您有所幫助,請以下面的評論形式提供任何反饋。 您的問題可能會也可能不會沒有那么麻煩,因此,這希望可以幫助您確定如何進行/在何處進行。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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