首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP XML 生成類別片段分析:陣列合併、編碼轉換、XPath 查詢

     編輯:PHP 綜合知識

代碼來源與定位

此片段疑為某 XML 生成類別 (如 sql2xml 或自訂 ORM) 的內部方法集合,處理選項設定、DOM 節點建立、UTF-8 編碼、陣列深度合併、XML 字串匯入、XPath 查詢等輔助功能。

核心功能模組解析

1. 選項設定與深度合併

// 設定選項,支援巢狀陣列覆蓋合併
function SetOptions($options) {
    foreach ($options as $option => $value) {
        if (is_array($value) && !$delete) {
            foreach ($value as $suboption => $subvalue) {
                $this->{$option}[$suboption] = $subvalue;
            }
        } else {
            $this->$option = $value;
        }
    }
}

// 陣列深度合併 (clobber 模式:後者覆蓋前者同鍵值)
function array_merge_clobber($a1, $a2) {
    if (!is_array($a1) || !is_array($a2)) return false;
    $newarray = $a1;
    foreach ($a2 as $key => $val) {
        if (is_array($val) && is_array($newarray[$key])) {
            $newarray[$key] = $this->array_merge_clobber($newarray[$key], $val);
        } else {
            $newarray[$key] = $val;
        }
    }
    return $newarray;
}

用途: 類別配置初始化,允許部分覆蓋巢狀設定 (如資料庫連線參數、輸出格式選項)。

2. DOM 節點建立擴充點 (Template Method 模式)


// 可被子類覆寫的掛鉤方法
function insertNewResult(&$metadata) { /* 建立  根節點 */ }
function insertNewRow($parent_row, $res, $key, &$metadata) { /* 建立  節點 */ }
function insertNewElement($parent, $res, $key, &$metadata, &$subrow) {
    return $parent->new_child($metadata[$key]["name"], $this->xml_encode(trim($res[$key])));
}
function addTableInfo($key, $value, &$metadata) { /* 擴充表資訊 */ }

設計模式: Template Method,核心流程在父類,關鍵節點建立委託子類自訂 (如自定義標籤名、屬性、CDATA 等)。

3. XML 編碼安全輸出

function xml_encode($text) {
    if (function_exists('iconv') && isset($this->encoding_from, $this->encoding_to)) {
        ini_set('track_errors', 1);
        // 逸出 & 和 < (非標籤情況)
        $text = iconv($this->encoding_from, $this->encoding_to,
            preg_replace('/&(?!#?\w+;)/', '&',
                preg_replace('/

關鍵點:

  • 支援 iconv 跨編碼轉換 (如 Big5 → UTF-8)。
  • 智慧逸出:& 非實體引用時轉 &amp;,< 非標籤時轉 &lt;。
  • PHP 4.0.6 相容性處理 (已過時)。

4. XML 字串匯入現有文檔

function doXmlString2Xml($string, $xpath = null) {
    // PHP 4.0.7+ 使用 DOMXML 物件操作
    // PHP 4.0.6 回退:字串拼接後重新解析 (效能差、易錯)
    // 支援 XPath 篩選匯入片段
    // 支援 root 路徑前綴 (在指定父節點下建立結構再匯入)
}

現代替代: DOMDocument::loadXML() + DOMXPath + importNode(),標準、高效、無版本相容包袱。

5. 編碼設定介面

function setEncoding($encoding_from = 'ISO-8859-1', $encoding_to = 'UTF-8') {
    $this->encoding_from = $encoding_from;
    $this->encoding_to = $encoding_to;
}

6. 父表關聯設定

function SetParentTables($parentTables) {
    foreach ($parentTables as $table => $parent) {
        $table_info['parent_table'][$table] = $parent;
    }
    $this->SetOptions(['user_tableInfo' => $table_info]);
}

用於主從表關聯 XML 輸出 (如訂單-明細),指定父表關鍵欄位。

7. XPath 查詢便利方法

function getXpathValue($expr) {
    $xpth = $this->xmldoc->xpath_new_context();
    $xnode = xpath_eval($xpth, $expr);
    if (isset($xnode->nodeset[0])) {
        return $xnode->nodeset[0]->children()[0]->content;
    }
    return null;
}

function getXpathChildValues($expr) {
    $xpth = $this->xmldoc->xpath_new_context();
    $xnode = xpath_eval($xpth, $expr);
    if (isset($xnode->nodeset[0])) {
        $values = [];
        foreach ($xnode->nodeset[0]->children() as $child) {
            $values[$child->{$this->tagname}] = $child->children()[0]->content;
        }
        return $values;
    }
    return null;
}

現代化重構建議 (PHP 8 + DOM)

class XmlBuilder {
    private DOMDocument $dom;
    private DOMElement $root;
    private string $encoding = 'UTF-8';

    public function __construct(string $rootName = 'root', string $encoding = 'UTF-8') {
        $this->dom = new DOMDocument('1.0', $encoding);
        $this->dom->formatOutput = true;
        $this->root = $this->dom->createElement($rootName);
        $this->dom->appendChild($this->root);
    }

    public function addResult(array $data, array $metadata): DOMElement {
        $result = $this->dom->createElement('result');
        foreach ($data as $row) {
            $rowEl = $this->dom->createElement('row');
            foreach ($row as $key => $value) {
                $el = $this->dom->createElement($metadata[$key]['name'] ?? $key);
                $el->textContent = (string)$value; // 自動逸出
                $rowEl->appendChild($el);
            }
            $result->appendChild($rowEl);
        }
        $this->root->appendChild($result);
        return $result;
    }

    public function importXmlString(string $xml, string $xpath = ''): void {
        $fragment = new DOMDocument();
        $fragment->loadXML($xml);
        $xpathObj = new DOMXPath($fragment);
        $nodes = $xpath ? $xpathObj->query($xpath) : [$fragment->documentElement];
        foreach ($nodes as $node) {
            $imported = $this->dom->importNode($node, true);
            $this->root->appendChild($imported);
        }
    }

    public function xpathValue(string $expr): ?string {
        $xpath = new DOMXPath($this->dom);
        $node = $xpath->query($expr)->item(0);
        return $node?->textContent;
    }

    public function xpathChildValues(string $expr): array {
        $xpath = new DOMXPath($this->dom);
        $node = $xpath->query($expr)->item(0);
        if (!$node) return [];
        $values = [];
        foreach ($node->childNodes as $child) {
            if ($child->nodeType === XML_ELEMENT_NODE) {
                $values[$child->localName] = $child->textContent;
            }
        }
        return $values;
    }

    public function save(string $filename): void { $this->dom->save($filename); }
    public function output(): string { return $this->dom->saveXML(); }
}

結語

此代碼片段展示了早期 PHP (DOMXML 擴充) 時代 XML 處理的常見模式:編碼轉換、Template Method 擴充、XPath 查詢、字串匯入。現代開發請直接使用標準 DOMDocument + DOMXPath,享受完整 Unicode 支援、命名空間處理、Schema 驗證、XSLT 轉換等企業級功能,且無需維護相容層代碼。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved