Skip to content

XMLParser CDATA content lost on Linux when foundCDATA not implemented #5280

@mrkprds

Description

@mrkprds

When a delegate implements foundCharacters but NOT foundCDATA:

  • macOS: CDATA content passed through foundCharacters
  • Linux: CDATA content lost entirely

Reproduction

macOS

import Foundation
#if canImport(FoundationXML)
import FoundationXML
#endif

class TestDelegate: NSObject, XMLParserDelegate {
    var foundText: [String] = []

    func parser(_ parser: XMLParser, foundCharacters string: String) {
        print("foundCharacters called with: '\(string)'")
        foundText.append(string)
    }

    func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {
        print("didEndElement: \(elementName), accumulated: '\(foundText.joined())'")
    }
}

let xml = """
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="html"><![CDATA[<b>Bold</b> text]]></string>
</resources>
"""

let data = Data(xml.utf8)
let parser = XMLParser(data: data)
let delegate = TestDelegate()
parser.delegate = delegate

print("Starting parse...")
let success = parser.parse()
print("Parse success: \(success)")
print("Total accumulated text: '\(delegate.foundText.joined())'")

Linux

import Foundation
#if canImport(FoundationXML)
import FoundationXML
#endif

class TestDelegate: XMLParserDelegate {
    var foundText: [String] = []

    func parser(_ parser: XMLParser, foundCharacters string: String) {
        print("foundCharacters called with: '\(string)'")
        foundText.append(string)
    }

    func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {
        print("didEndElement: \(elementName), accumulated: '\(foundText.joined())'")
    }
}

let xml = """
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="html"><![CDATA[<b>Bold</b> text]]></string>
</resources>
"""

let data = Data(xml.utf8)
let parser = XMLParser(data: data)
let delegate = TestDelegate()
parser.delegate = delegate

print("Starting parse...")
let success = parser.parse()
print("Parse success: \(success)")
print("Total accumulated text: '\(delegate.foundText.joined())'")

macOS Output

Starting parse...
foundCharacters called with: '
    '
foundCharacters called with: '<b>Bold</b> text'
didEndElement: string, accumulated: '
    <b>Bold</b> text'
foundCharacters called with: '
'
didEndElement: resources, accumulated: '
    <b>Bold</b> text
'
Parse success: true
Total accumulated text: '
    <b>Bold</b> text
'

Linux Output

Starting parse...
foundCharacters called with: '
    '
didEndElement: string, accumulated: '
    '
foundCharacters called with: '
'
didEndElement: resources, accumulated: '

'
Parse success: true
Total accumulated text: '

'

The CDATA content <b>Bold</b> text is present on macOS but completely missing on Linux.


Environment

  • Swift: 6.2 (swift-6.2-RELEASE)
  • macOS: Sequoia 15.1 (Build 26.0.1)
  • Linux: Ubuntu 24.04.3 LTS (Docker: swift:6.2)

Related Issues

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions