I 've been trying to parse some part of xml including CDATA and I don't understand why the cdata was not showing at all. I ve been trying to solve this problem with SWXMLHASH
Below is the xml
<DOC title=\"Effect\" type=\"EE\">
<SECTION title=\"\">
<ARTICLE title=\"1. Main Effect\">
<PARAGRAPH tagName=\"p\" textIndent=\"0\" marginLeft=\"0\">
<![CDATA[Pain due to several diseases]]>
</PARAGRAPH>
</ARTICLE>
<ARTICLE title=\"2. Indications\">
<PARAGRAPH tagName=\"p\" textIndent=\"0\" marginLeft=\"0\">
<![CDATA[Rheuatism]]>
</PARAGRAPH>
</ARTICLE>
</SECTION>
</DOC>
And below is my code
import SwiftUI
import SWXMLHash
struct Article : XMLIndexerDeserializable, Identifiable, Hashable {
let id = UUID()
let title : String
let paragraph : [String]
enum CodingKeys: String, CodingKey {
case article = "ARTICLE"
case paragraph = "PARAGRAPH"
}
static func deserialize(_ node: XMLIndexer) throws -> Article {
return try Article (
title: node.value(ofAttribute: "title"),
paragraph: node["ARTICLE"]["PARAGRAPH"].value()
)
}
}
struct MyDrug: View {
@State var drugNameSearch = [DrugNameSearch]()
var body: some View {
GeometryReader{geometry in
ForEach(drugNameSearch, id: \.self){item in
VStack(alignment: .leading, spacing: geometry.size.height/50){
let xmlEffect = item.effect //this is xml same as above
let xml = XMLHash.config { config in
config.shouldProcessLazily = true
}.parse(xmlEffect)
let effectsArticle: [Article] = try! xml["DOC"]["SECTION"]["ARTICLE"].value()
ForEach(effectsArticle, id: \.self){
Text($0.title)
.foregroundColor(Color("tabBarBackground"))
.font(.body)
ForEach($0.paragraph, id: \.self){i in
Text(i)
.foregroundColor(Color("tabBarBackground"))
.font(.body)
}
}
}
}
}
}
}
With that code, title of Article comes right, but no Paragraph data comes and no error at all. Please give me some advice..
The main issue is that, in your custom Article
type, when the value of PARAGRAPH is retrieved, it should instead be like: paragraph: node["PARAGRAPH"].value()
This is because the node is already indexed to the ARTICLE so you don't have to specify that index. So, the whole Article type would look like:
struct Article : XMLIndexerDeserializable, Identifiable, Hashable {
let id = UUID()
let title : String
let paragraph : [String]
enum CodingKeys: String, CodingKey {
case article = "ARTICLE"
case paragraph = "PARAGRAPH"
}
static func deserialize(_ node: XMLIndexer) throws -> Article {
return try Article (
title: node.value(ofAttribute: "title"),
paragraph: node["PARAGRAPH"].value()
)
}
}
One other thing to check... if there won't be more than one paragraph, then that can be defined as String
instead of [String]
.