Skip to content

Commit

Permalink
xml기능 추가
Browse files Browse the repository at this point in the history
// xml atributes 미구현
  • Loading branch information
HanweeeeLee committed Oct 13, 2020
1 parent 528426f commit 014f3cf
Show file tree
Hide file tree
Showing 4 changed files with 247 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
78CE306E2534674E0020E536 /* FlexibleModelProtocolTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78CE306D2534674E0020E536 /* FlexibleModelProtocolTests.swift */; };
78CE30702534674E0020E536 /* FlexibleModelProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 78CE30622534674E0020E536 /* FlexibleModelProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; };
78CE307C2534677E0020E536 /* FlexibleModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78CE307B2534677E0020E536 /* FlexibleModelProtocol.swift */; };
78D95D7D2535B0FB009A379F /* HWXMLEelement.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78D95D7B2535B0FB009A379F /* HWXMLEelement.swift */; };
78D95D7E2535B0FB009A379F /* HWXMLParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78D95D7C2535B0FB009A379F /* HWXMLParser.swift */; };
/* End PBXBuildFile section */

/* Begin PBXContainerItemProxy section */
Expand All @@ -31,6 +33,8 @@
78CE306D2534674E0020E536 /* FlexibleModelProtocolTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FlexibleModelProtocolTests.swift; sourceTree = "<group>"; };
78CE306F2534674E0020E536 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
78CE307B2534677E0020E536 /* FlexibleModelProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FlexibleModelProtocol.swift; sourceTree = "<group>"; };
78D95D7B2535B0FB009A379F /* HWXMLEelement.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HWXMLEelement.swift; sourceTree = "<group>"; };
78D95D7C2535B0FB009A379F /* HWXMLParser.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HWXMLParser.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand Down Expand Up @@ -75,6 +79,8 @@
children = (
78CE307B2534677E0020E536 /* FlexibleModelProtocol.swift */,
78CE30622534674E0020E536 /* FlexibleModelProtocol.h */,
78D95D7C2535B0FB009A379F /* HWXMLParser.swift */,
78D95D7B2535B0FB009A379F /* HWXMLEelement.swift */,
78CE30632534674E0020E536 /* Info.plist */,
);
path = FlexibleModelProtocol;
Expand Down Expand Up @@ -198,7 +204,9 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
78D95D7E2535B0FB009A379F /* HWXMLParser.swift in Sources */,
78CE307C2534677E0020E536 /* FlexibleModelProtocol.swift in Sources */,
78D95D7D2535B0FB009A379F /* HWXMLEelement.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,18 @@ extension FlexibleModelProtocol {
return returnValue
}

static func fromXML<T:FlexibleModelProtocol>(xmlData:Data?,object:T) -> T? { //아직 미구현
static func fromXML<T:FlexibleModelProtocol>(xmlData:Data?,object:T) -> T? {
var returnValue:T? = nil

if let data = xmlData {
let parser:HWXMLParser = HWXMLParser()
if let xmlElement = parser.parse(data: data) {
if let dic = parser.toDictionary(element: xmlElement) {
returnValue = fromDictionary(dictionary: dic, object: object)
}
}
}

return returnValue
}

Expand Down Expand Up @@ -73,8 +83,10 @@ extension FlexibleModelProtocol {
return jsonString
}

func toXML() -> String { //아직 미구현
return ""
func toXML() -> String? {
let dic = toDictionary()
let parser:HWXMLParser = HWXMLParser()
return parser.toXMLString(dictionary: dic)
}

func toDictionary() -> Dictionary<String,Any>? {
Expand Down
27 changes: 27 additions & 0 deletions FlexibleModelProtocol/FlexibleModelProtocol/HWXMLEelement.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
//
// HWXMLEelement.swift
// XMLParseTest
//
// Created by hanwe lee on 2020/10/13.
//

import UIKit

public class HWXMLEelement: NSObject {

internal weak var parentsElement:HWXMLEelement?
internal var childrenEelement:Array<HWXMLEelement> = Array()
internal var name:String
internal var attributes:[String:String] = Dictionary()
internal var value:String = ""

public init(name:String) {
self.name = name
}

public convenience init(name:String,parentsElement:HWXMLEelement) {
self.init(name:name)
self.parentsElement = parentsElement
}

}
197 changes: 197 additions & 0 deletions FlexibleModelProtocol/FlexibleModelProtocol/HWXMLParser.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
//
// HWXMLParser.swift
// XMLParseTest
//
// Created by hanwe lee on 2020/10/12.
//

import Foundation

public class HWXMLParser:NSObject { //only supports utf-8 formmat

//MARK: private property
private var parser:XMLParser? = nil
private var elementStack:Array<HWXMLEelement> = Array()
private var rootEelement:HWXMLEelement? = nil

//MARK: public property

//MARK: lifeCycle

//MARK: private func

private func makeXMLtoDictionary(dictionary:inout [String:Any], element:HWXMLEelement) {
let children:Array<HWXMLEelement> = element.childrenEelement
for i in 0..<children.count {
if children[i].childrenEelement.count == 0 {
if children[i].attributes.count > 0 {//todo attributes 적용
dictionary[children[i].name] = children[i].value
}
else {
dictionary[children[i].name] = children[i].value
}
}
else {
var newDictionary:[String:Any] = Dictionary()
makeXMLtoDictionary(dictionary: &newDictionary, element: children[i])
if dictionary[children[i].name] == nil {
dictionary[children[i].name] = newDictionary
}
else {
if (dictionary[children[i].name] as? Array<[String:Any]>) != nil {
var newArray:Array<[String:Any]> = Array()
newArray += (dictionary[children[i].name] as! Array<[String:Any]>)
newArray.append(newDictionary)
dictionary[children[i].name] = newArray
}
else {
var newArray:Array<[String:Any]> = Array()
newArray.append(dictionary[children[i].name] as! [String:Any])
newArray.append(newDictionary)
dictionary[children[i].name] = newArray
}
}
}
}
}

private func makeXMLElementFromDictionary(element:inout HWXMLEelement,dictionary:[String:Any]) {
let allKeys:Array<String> = Array(dictionary.keys)
for i in 0..<allKeys.count {
let key = allKeys[i]
if (dictionary[key] as? Array<[String:Any]>) != nil {
let array:Array<[String:Any]> = (dictionary[key] as! Array<[String:Any]>)
for j in 0..<array.count {
var newElemnet:HWXMLEelement = HWXMLEelement(name: key, parentsElement: element)
makeXMLElementFromDictionary(element: &newElemnet, dictionary: array[j])
element.childrenEelement.append(newElemnet)
}
}
else if (dictionary[key] as? [String:Any]) != nil {
var newElement:HWXMLEelement = HWXMLEelement(name: key, parentsElement: element)
makeXMLElementFromDictionary(element: &newElement, dictionary: (dictionary[key] as! [String:Any]))
element.childrenEelement.append(newElement)
}
else if (dictionary[key] as? String) != nil {
let newElement:HWXMLEelement = HWXMLEelement(name: key, parentsElement: element)
newElement.value = (dictionary[key] as! String)
element.childrenEelement.append(newElement)
}
else {
//unexpected
}
}
}

private func makeXMLStringFromXMLElement(element:HWXMLEelement,beforeString:String) -> String {
var returnString:String = beforeString
if element.childrenEelement.count > 0 {
returnString += "<\(element.name)>\n"
for i in 0..<element.childrenEelement.count {
let childElement:HWXMLEelement = element.childrenEelement[i]
returnString = makeXMLStringFromXMLElement(element: childElement, beforeString: returnString)

}
returnString += "</\(element.name)>\n"
}
else {
returnString += "<\(element.name)>\(element.value)\("</\(element.name)>")\n"
}
return returnString
}

//MARK: public func

public func parse(data:Data) -> HWXMLEelement? {
self.parser = XMLParser(data: data)
self.parser?.delegate = self
self.parser?.parse()
return self.rootEelement
}

public func toDictionary(element:HWXMLEelement) -> [String:Any]? {
var returnValue:[String:Any]? = nil
var rootDic:[String:Any] = Dictionary()
var newDic:[String:Any] = Dictionary()
makeXMLtoDictionary(dictionary: &newDic, element: element)
rootDic[element.name] = newDic
returnValue = rootDic
return returnValue
}

public func toJson(element:HWXMLEelement) -> Data? {
var returnValue:Data? = nil

if let dic = toDictionary(element: element) {
do {
let jsonData = try JSONSerialization.data(withJSONObject: dic, options: .prettyPrinted)
returnValue = jsonData
} catch {

}
}

return returnValue
}

public func toXMLElement(dictionary:[String:Any]) -> HWXMLEelement? {
var returnValue:HWXMLEelement? = nil
let keys = Array(dictionary.keys)
for i in 0..<keys.count {
var element:HWXMLEelement = HWXMLEelement(name: keys[i])
if (dictionary[keys[i]] as? Array<[String:Any]>) != nil {
print("unexpected error")
}
else {
makeXMLElementFromDictionary(element: &element, dictionary: dictionary[keys[i]] as! [String : Any])
returnValue = element
}
}
return returnValue
}

public func toXMLString(dictionary:[String:Any]) -> String? {
var returnValue:String? = nil
if let root:HWXMLEelement = toXMLElement(dictionary: dictionary) {
let header:String = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"
returnValue = makeXMLStringFromXMLElement(element: root, beforeString: header)
}
return returnValue
}

}

extension HWXMLParser:XMLParserDelegate {
public func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String] = [:]) {
if self.elementStack.count > 0 {
let newElement:HWXMLEelement = HWXMLEelement.init(name: elementName, parentsElement: self.elementStack.last!)
newElement.attributes = attributeDict
self.elementStack.last!.childrenEelement.append(newElement)
self.elementStack.append(newElement)
}
else {
let newElement:HWXMLEelement = HWXMLEelement.init(name: elementName)
newElement.attributes = attributeDict
self.rootEelement = newElement
self.elementStack.append(newElement)
}

}

public func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {
if self.elementStack.count > 0 {
if self.elementStack.last!.name == elementName {
elementStack.removeLast()
}
}
}

public func parser(_ parser: XMLParser, foundCharacters string: String) {
if string != "\n" && string != "" {
if self.elementStack.count > 0 {
self.elementStack.last!.value = string
}
}
}

}

0 comments on commit 014f3cf

Please sign in to comment.