@@ -718,36 +718,55 @@ open class XMLNode: NSObject, NSCopying {
718
718
@abstract Returns the local name bar in foo:bar.
719
719
*/
720
720
open class func localName( forName name: String ) -> String {
721
- // return name.withCString {
722
- // var length: Int32 = 0
723
- // let result = xmlSplitQName3(UnsafePointer<xmlChar>($0), &length)
724
- // return String.fromCString(UnsafePointer<CChar>(result)) ?? ""
725
- // }
726
- NSUnimplemented ( )
721
+ if let localName = _CFXMLSplitQualifiedName ( name) {
722
+ return String ( cString: localName)
723
+ } else {
724
+ return name
725
+ }
727
726
}
728
727
729
728
/*!
730
729
@method localNameForName:
731
730
@abstract Returns the prefix foo in the name foo:bar.
732
731
*/
733
732
open class func prefix( forName name: String ) -> String ? {
734
- // return name.withCString {
735
- // var result: UnsafeMutablePointer<xmlChar> = nil
736
- // let unused = xmlSplitQName2(UnsafePointer<xmlChar>($0), &result)
737
- // defer {
738
- // xmlFree(result )
739
- // xmlFree(UnsafeMutablePointer<xmlChar>(unused))
740
- // }
741
- // return String.fromCString(UnsafePointer<CChar>(result))
742
- // }
743
- NSUnimplemented ( )
733
+ var size : size_t = 0
734
+ if _CFXMLGetLengthOfPrefixInQualifiedName ( name , & size ) {
735
+ return name . withCString {
736
+ $0 . withMemoryRebound ( to : UInt8 . self , capacity : size ) {
737
+ return String ( decoding : UnsafeBufferPointer ( start : $0 , count : size ) , as : UTF8 . self )
738
+ }
739
+ }
740
+ } else {
741
+ return nil
742
+ }
744
743
}
745
744
746
745
/*!
747
746
@method predefinedNamespaceForPrefix:
748
747
@abstract Returns the namespace belonging to one of the predefined namespaces xml, xs, or xsi
749
748
*/
750
- open class func predefinedNamespace( forPrefix name: String ) -> XMLNode ? { NSUnimplemented ( ) }
749
+ private static func defaultNamespace( prefix: String , value: String ) -> XMLNode {
750
+ let node = XMLNode ( kind: . namespace)
751
+ node. name = prefix
752
+ node. objectValue = value
753
+ return node
754
+ }
755
+ private static let _defaultNamespaces : [ XMLNode ] = [
756
+ XMLNode . defaultNamespace ( prefix: " xml " , value: " http://www.w3.org/XML/1998/namespace " ) ,
757
+ XMLNode . defaultNamespace ( prefix: " xml " , value: " http://www.w3.org/2001/XMLSchema " ) ,
758
+ XMLNode . defaultNamespace ( prefix: " xml " , value: " http://www.w3.org/2001/XMLSchema-instance " ) ,
759
+ ]
760
+
761
+ internal static let _defaultNamespacesByPrefix : [ String : XMLNode ] =
762
+ Dictionary ( XMLNode . _defaultNamespaces. map { ( $0. name!, $0) } , uniquingKeysWith: { old, _ in old } )
763
+
764
+ internal static let _defaultNamespacesByURI : [ String : XMLNode ] =
765
+ Dictionary ( XMLNode . _defaultNamespaces. map { ( $0. stringValue!, $0) } , uniquingKeysWith: { old, _ in old } )
766
+
767
+ open class func predefinedNamespace( forPrefix name: String ) -> XMLNode ? {
768
+ return XMLNode . _defaultNamespacesByPrefix [ name]
769
+ }
751
770
752
771
/*!
753
772
@method description
@@ -777,7 +796,39 @@ open class XMLNode: NSObject, NSCopying {
777
796
@method canonicalXMLStringPreservingComments:
778
797
@abstract W3 canonical form (http://www.w3.org/TR/xml-c14n). The input option NSXMLNodePreserveWhitespace should be set for true canonical form.
779
798
*/
780
- open func canonicalXMLStringPreservingComments( _ comments: Bool ) -> String { NSUnimplemented ( ) }
799
+ open func canonicalXMLStringPreservingComments( _ comments: Bool ) -> String {
800
+ var result = " "
801
+ switch kind {
802
+ case . text:
803
+ let scanner = Scanner ( string: self . stringValue ?? " " )
804
+ let toReplace = CharacterSet ( charactersIn: " &<> \r " )
805
+ while let string = scanner. scanUpToCharacters ( from: toReplace) {
806
+ result += string
807
+ if scanner. scanString ( " & " ) != nil {
808
+ result += " & "
809
+ } else if scanner. scanString ( " < " ) != nil {
810
+ result += " < "
811
+ } else if scanner. scanString ( " > " ) != nil {
812
+ result += " > "
813
+ } else if scanner. scanString ( " \r " ) != nil {
814
+ result += " 
 "
815
+ } else {
816
+ fatalError ( " We scanned up to one of the characters to replace, but couldn't find it when we went to consume it. " )
817
+ }
818
+ }
819
+ result += scanner. string [ scanner. currentIndex... ]
820
+
821
+
822
+ case . comment:
823
+ if comments {
824
+ result = " <!-- \( stringValue ?? " " ) --> "
825
+ }
826
+
827
+ default : break
828
+ }
829
+
830
+ return result
831
+ }
781
832
782
833
/*!
783
834
@method nodesForXPath:error:
@@ -786,7 +837,7 @@ open class XMLNode: NSObject, NSCopying {
786
837
*/
787
838
open func nodes( forXPath xpath: String ) throws -> [ XMLNode ] {
788
839
guard let nodes = _CFXMLNodesForXPath ( _xmlNode, xpath) else {
789
- NSUnimplemented ( )
840
+ return [ ]
790
841
}
791
842
792
843
var result : [ XMLNode ] = [ ]
@@ -803,12 +854,14 @@ open class XMLNode: NSObject, NSCopying {
803
854
@abstract Returns the objects resulting from applying an XQuery to this node using the node as the context item ("."). Constants are a name-value dictionary for constants declared "external" in the query. normalizeAdjacentTextNodesPreservingCDATA:NO should be called if there are adjacent text nodes since they are not allowed under the XPath/XQuery Data Model.
804
855
@returns An array whose elements are kinds of NSArray, NSData, NSDate, NSNumber, NSString, NSURL, or NSXMLNode.
805
856
*/
857
+ @available ( * , unavailable, message: " XQuery is not available in swift-corelibs-foundation " )
806
858
open func objects( forXQuery xquery: String , constants: [ String : Any ] ? ) throws -> [ Any ] {
807
- NSUnimplemented ( )
859
+ NSUnsupported ( )
808
860
}
809
861
862
+ @available ( * , unavailable, message: " XQuery is not available in swift-corelibs-foundation " )
810
863
open func objects( forXQuery xquery: String ) throws -> [ Any ] {
811
- NSUnimplemented ( )
864
+ NSUnsupported ( )
812
865
}
813
866
814
867
internal var _childNodes : Set < XMLNode > = [ ]
0 commit comments