1
1
/*
2
2
This source file is part of the Swift.org open source project
3
3
4
- Copyright (c) 2022-2024 Apple Inc. and the Swift project authors
4
+ Copyright (c) 2022 Apple Inc. and the Swift project authors
5
5
Licensed under Apache License v2.0 with Runtime Library Exception
6
6
7
7
See https://swift.org/LICENSE.txt for license information
10
10
11
11
import Foundation
12
12
13
+ // On non-Darwin platforms, Foundation's XML support is vended as a separate module:
14
+ // https://github.com/apple/swift-corelibs-foundation/blob/main/Docs/ReleaseNotes_Swift5.md#dependency-management
15
+ #if canImport(FoundationXML)
16
+ import FoundationXML
17
+ #endif
18
+
13
19
/// A basic XML parser that extracts the first `id` attribute found in the given SVG.
14
20
///
15
21
/// This is a single-purpose tool and should not be used for general-purpose SVG parsing.
@@ -19,19 +25,14 @@ enum SVGIDExtractor {
19
25
/// Exposed for testing. The sibling `extractID(from: URL)` method is intended to be
20
26
/// used within SwiftDocC.
21
27
static func _extractID( from data: Data ) -> String ? {
22
- // FIXME: Revert this and resume using XMLParser when rdar://138726860 is integrated into a Swift toolchain.
23
- for capitalization in [ " id " , " ID " , " Id " , " iD " ] {
24
- guard let idAttributeRange = data. firstRange ( of: Data ( " \( capitalization) = \" " . utf8) , in: data. indices) else {
25
- continue
26
- }
27
-
28
- guard let endQuote = data. firstRange ( of: Data ( " \" " . utf8) , in: idAttributeRange. upperBound... ) else {
29
- continue
30
- }
31
-
32
- return String ( data: data [ idAttributeRange. endIndex ..< endQuote. lowerBound] , encoding: . utf8)
33
- }
34
- return nil
28
+ let delegate = SVGIDParserDelegate ( )
29
+ let svgParser = XMLParser ( data: data)
30
+ svgParser. delegate = delegate
31
+
32
+ // The delegate aborts the parsing when it finds the ID so the larger parsing operation is not "successful"
33
+ _ = svgParser. parse ( )
34
+
35
+ return delegate. id
35
36
}
36
37
37
38
/// Returns the first `id` attribute found in the given SVG, if any.
@@ -46,3 +47,22 @@ enum SVGIDExtractor {
46
47
return _extractID ( from: data)
47
48
}
48
49
}
50
+
51
+ private class SVGIDParserDelegate : NSObject , XMLParserDelegate {
52
+ var id : String ?
53
+
54
+ func parser(
55
+ _ parser: XMLParser ,
56
+ didStartElement elementName: String ,
57
+ namespaceURI: String ? ,
58
+ qualifiedName qName: String ? ,
59
+ attributes attributeDict: [ String : String ] = [ : ]
60
+ ) {
61
+ guard let id = attributeDict [ " id " ] ?? attributeDict [ " ID " ] ?? attributeDict [ " iD " ] ?? attributeDict [ " Id " ] else {
62
+ return
63
+ }
64
+
65
+ self . id = id
66
+ parser. abortParsing ( )
67
+ }
68
+ }
0 commit comments