You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用PHP的SimpleXMLElement生成指定格式的XML?

使用PHP SimpleXMLElement生成指定命名空间XML的正确方法

问题概述

需要从关联数组生成带多命名空间的指定结构XML,使用SimpleXMLElement时遇到以下问题:

  • 子元素命名空间错误,默认继承根元素的pt命名空间而非指定的request_meta
  • 布尔值false被生成自闭合标签,不符合目标结构
  • 操作过程中丢失XML声明和根元素<pt:request>

目标XML结构

<pt:request xmlns:pt="urn:logalty:schemas:core:1.0" xmlns:identity="urn:logalty:schemas:core:identity:1.0" xmlns:process_meta="urn:logalty:schemas:process:meta:1.0" xmlns:ptforms="urn:logalty:schemas:forms:1.0" xmlns:request_meta="urn:logalty:schemas:request:meta:1.0">
    <pt:request_meta>
        <request_meta:service>PT0005_ACCEPTANCEXPRESS</request_meta:service>
        <request_meta:time2close unit="d" value="28"/>
        <request_meta:time2save unit="d" value="1825"/>
        <request_meta:lopd>0</request_meta:lopd>
        <request_meta:retryprotocol>3</request_meta:retryprotocol>
        <request_meta:synchronous>false</request_meta:synchronous>
        <request_meta:tsa>0</request_meta:tsa>
        <request_meta:userdefined name="LGT_SDKJava">4.13.2</request_meta:userdefined>
    </pt:request_meta>
</pt:request>

关联数组数据源

$logalty_data = [
    'request_meta:service' => 'instalacion_id_'.$id,
    'request_meta:time2close unit="d" value="28"' => '',
    'request_meta:time2save unit="d" value="1825"' => '',
    'request_meta:lopd' => 0,
    'request_meta:retryprotocol' => 3,
    'request_meta:synchronous' => false,
    'request_meta:tsa' => 0,
    'request_meta:userdefined name="php"' => '8.1.6'
];

当前错误输出

<pt:request_meta>
    <pt:service>instalacion_id_1</pt:service>
    <pt:time2close unit="d" value="28"/>
    <pt:time2save unit="d" value="1825"/>
    <pt:lopd>0</pt:lopd>
    <pt:retryprotocol>3</pt:retryprotocol>
    <pt:synchronous/>
    <pt:tsa>0</pt:tsa>
    <pt:userdefined name="php">8.1.6</pt:userdefined>
</pt:request_meta>

解决方案

关键处理要点

  1. 显式管理命名空间:创建元素时必须指定对应的命名空间URI,不能依赖自动继承
  2. 拆分标签与属性:手动解析数组键中的标签名和属性部分,避免混写导致解析错误
  3. 特殊值处理:将布尔值转为字符串,避免生成不符合要求的自闭合标签
  4. 格式化输出:借助DOMDocument保留XML声明和缩进格式

完整实现代码

<?php
$id = 1;
$logalty_data = [
    'request_meta:service' => 'instalacion_id_' . $id,
    'request_meta:time2close unit="d" value="28"' => '',
    'request_meta:time2save unit="d" value="1825"' => '',
    'request_meta:lopd' => 0,
    'request_meta:retryprotocol' => 3,
    'request_meta:synchronous' => false,
    'request_meta:tsa' => 0,
    'request_meta:userdefined name="php"' => '8.1.6'
];

// 定义所有命名空间映射
$namespaces = [
    'pt' => 'urn:logalty:schemas:core:1.0',
    'identity' => 'urn:logalty:schemas:core:identity:1.0',
    'process_meta' => 'urn:logalty:schemas:process:meta:1.0',
    'ptforms' => 'urn:logalty:schemas:forms:1.0',
    'request_meta' => 'urn:logalty:schemas:request:meta:1.0'
];

// 创建带完整命名空间的根元素
$root = new SimpleXMLElement(
    '<pt:request xmlns:pt="' . $namespaces['pt'] . '" 
      xmlns:identity="' . $namespaces['identity'] . '" 
      xmlns:process_meta="' . $namespaces['process_meta'] . '" 
      xmlns:ptforms="' . $namespaces['ptforms'] . '" 
      xmlns:request_meta="' . $namespaces['request_meta'] . '"/>'
);

// 创建pt:request_meta元素(归属pt命名空间)
$requestMeta = $root->addChild('pt:request_meta', '', $namespaces['pt']);

foreach ($logalty_data as $key => $value) {
    // 拆分命名空间前缀和标签内容
    list($prefix, $tagPart) = explode(':', $key, 2);
    
    // 解析标签名和属性
    $tagName = $tagPart;
    $attributes = [];
    if (strpos($tagPart, ' ') !== false) {
        list($tagName, $attrStr) = explode(' ', $tagPart, 2);
        // 正则提取属性键值对
        preg_match_all('/(\w+)="([^"]+)"/', $attrStr, $matches);
        $attributes = array_combine($matches[1], $matches[2]);
    }
    
    // 获取当前命名空间的URI
    $nsUri = $namespaces[$prefix];
    
    // 创建指定命名空间的子元素
    $element = $requestMeta->addChild($prefix . ':' . $tagName, '', $nsUri);
    
    // 添加元素属性
    foreach ($attributes as $attrName => $attrValue) {
        $element->addAttribute($attrName, $attrValue);
    }
    
    // 处理文本内容:布尔值转字符串,空值跳过(保持自闭合)
    if ($value !== '') {
        $element[0] = is_bool($value) ? ($value ? 'true' : 'false') : $value;
    }
}

// 转换为DOMDocument以保留XML声明和格式化输出
$dom = dom_import_simplexml($root)->ownerDocument;
$dom->formatOutput = true;
echo $dom->saveXML();
?>

代码说明

  • 根元素初始化时显式声明所有命名空间,确保XML结构完整
  • 遍历数组时拆分每个键的命名空间、标签名和属性,分别处理
  • 创建子元素时指定对应命名空间URI,确保标签前缀正确
  • 对布尔值false做字符串转换,避免生成自闭合标签
  • 使用DOMDocument格式化XML,输出带声明和缩进的标准结构

内容的提问来源于stack exchange,提问作者scorpions77

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 12:05:01