直接上代码:

<?php

/**
 * 将 XML 字符串转成 JSON 字符串
 *
 * @param string $xmlString
 * @return string
 */
function xmlToJson(string $xmlString): string
{
    $doc = new DOMDocument();
    $doc->loadXML($xmlString, LIBXML_NOCDATA);

    $root = $doc->documentElement;

    $array = xml_to_array($root);

    return json_encode($array, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
}

function xml_to_array(DOMNode $node)
{
    $output = [];

    // Process attributes
    if ($node->hasAttributes()) {
        foreach ($node->attributes as $attr) {
            $output['@attributes'][$attr->nodeName] = $attr->nodeValue;
        }
    }

    // Process child nodes
    if ($node->hasChildNodes()) {
        $textContent = '';
        $cdataContent = '';
        $childElements = [];

        foreach ($node->childNodes as $child) {
            if ($child->nodeType === XML_ELEMENT_NODE) {
                $childArray = xml_to_array($child);
                $childName = $child->nodeName;

                if (!isset($childElements[$childName])) {
                    $childElements[$childName] = [];
                }
                $childElements[$childName][] = $childArray;
            } elseif ($child->nodeType === XML_TEXT_NODE) {
                $textContent .= $child->nodeValue;
            } elseif ($child->nodeType === XML_CDATA_SECTION_NODE) {
                $cdataContent .= $child->nodeValue;
            }
        }

        // Add child elements to output
        foreach ($childElements as $name => $items) {
            if (count($items) === 1) {
                $output[$name] = $items[0];
            } else {
                $output[$name] = $items;
            }
        }

        // Add text or cdata content if exists
        $textContent = trim($textContent);
        $cdataContent = trim($cdataContent);

        if (strlen($cdataContent) > 0) {
            $output['@cdata'] = $cdataContent;
        }

        if (strlen($textContent) > 0) {
            $output['@text'] = $textContent;
        }

        // If no child elements and only one text node, simplify output
        if (empty($childElements) && count($output) === 1 && isset($output['@text'])) {
            $output = $output['@text'];
        }
    } else {
        // No children, just text content
        $output = $node->nodeValue;
    }

    return $output;
}

// 示例
$filepath = '/Users/tony/crowall/xxxx.kml';

$xml = file_get_contents($filepath);

echo xmlToJson($xml);

标签: kml, 航线文件, json

添加新评论