使用xmlread 直接提取批注范围内的内容

function extractCommentRangeContent($inputXml, $commentId = '0')
{
    if (!file_exists($inputXml)) {
        error_log("❌ 输入文件不存在: $inputXml");
        return false;
    }

    $wordMLNamespace = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main';
    $reader = new XMLReader();

    if (!$reader->open($inputXml)) {
        error_log("❌ 无法打开 XML 文件: $inputXml");
        return false;
    }

    $contentToWrite = '';
    $stage = 'search_start';
    $depth = 0;

    while ($reader->read()) {
        if ($reader->nodeType === XMLReader::ELEMENT) {
            if ($reader->localName === 'commentRangeStart' && $reader->namespaceURI === $wordMLNamespace) {
                $id = $reader->getAttributeNs('id', $wordMLNamespace);
                if ($id === $commentId) {
                    $stage = 'capture_range';
                    appendStartElement($reader, $contentToWrite);
                    $depth++;
                }
            } elseif ($stage === 'capture_range') {
                if ($reader->localName === 'commentReference' && $reader->namespaceURI === $wordMLNamespace) {
                    $id = $reader->getAttributeNs('id', $wordMLNamespace);
                    if ($id === $commentId) {
                        appendStartElement($reader, $contentToWrite);
                        $stage = 'done';
                        continue;
                    }
                }

                appendStartElement($reader, $contentToWrite);
                if (!$reader->isEmptyElement) {
                    $depth++;
                }
            }
        } elseif ($reader->nodeType === XMLReader::END_ELEMENT && $stage === 'capture_range') {
            $contentToWrite .= '</' . $reader->name . '>';
            $depth--;
        } elseif (($reader->nodeType === XMLReader::TEXT || $reader->nodeType === XMLReader::CDATA) && $stage === 'capture_range') {
            $contentToWrite .= htmlspecialchars($reader->value);
        }
    }

    $reader->close();

    if ($stage !== 'done') {
        error_log("❌ 未找到完整的 commentRange 或 commentReference,ID=$commentId");
        return false;
    }

    error_log("✅ 成功提取从 commentRangeStart 到 commentReference ($commentId) 的内容");
    return $contentToWrite;
}

function appendStartElement($reader, &$output)
{
    $output .= '<' . $reader->name;
    if ($reader->hasAttributes) {
        while ($reader->moveToNextAttribute()) {
            $output .= ' ' . $reader->name . '="' . htmlspecialchars($reader->value) . '"';
        }
        $reader->moveToElement();
    }
    $output .= $reader->isEmptyElement ? '/>' : '>';
}
Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐