提问人:markb 提问时间:9/24/2022 更新时间:9/24/2022 访问量:249
在 Swift 中附加元素后输出 XML 文档
Outputting an XML document in Swift after appending an element into it
问:
在 Swift 中,有没有办法在通过函数传递 XML 文档后将元素添加到 XML 文档中?
例如,如果我将 的文本传入一个函数,我是否可以将其附加到 XML 文件中并将其另存为新的 XML 文档?<original>
输入 XML
<original>item-id-01</original>
自定义函数
func doThings(_ string: String) -> String { ... }
doThings("item-id-01")
输出 XML
<original>item-id-01</original>
<destination>output from custom function</destination>
我正在尝试在不使用库的情况下解析 XML 文件,但我看到的所有教程似乎都只展示了如何将一个元素追加到数组中,并将其显示到 UI 中。
也就是说,大多数示例:
<book> --> struct Book {
<title>My book</title> --> var title: String
<author>Dr. ABC</author> --> var author: String
</book> --> }
和 将搜索 ,然后将其附加到 的数组中。这似乎是XML解析的流行用途,因为它是JSON成为标准之前获取数据的方式。XMLParser
XMLParserDelegate
elementName == "book"
var books: [Book]
但是,我希望能够传入我的XML文件:
<?xml version="1.0" encoding="UTF-8"?>
<data version="1.2">
<file file-location="Local/Folder/file-a.txt" original="192.168.0.1" destination="192.168.0.2">
<header>
<tool id="com.apple.TextEdit" name="TextEdit" version="14.0" build="123ABC"/>
</header>
<body>
<item id="item-id-01" xml:space="preserve">
<original>item-id-01</original>
<note>Notes: no notes recorded</note>
</item>
</body>
</file>
<file file-location="Local/Folder/file-b.txt" original="192.168.10.1" destination="192.168.10.2">
<header>
<tool id="com.apple.TextEdit" name="TextEdit" version="14.0" build="123ABC"/>
</header>
<body>
<item id="item-id-02" xml:space="preserve">
<original>item-id-02</original>
<note>Notes: no notes recorded</note>
</item>
</body>
</file>
</data>
获取所有元素,将它们传递到函数中,并有一个如下所示的 XML 文档:<original>
doThings()
<?xml version="1.0" encoding="UTF-8"?>
<data version="1.2">
<file file-location="Local/Folder/file-a.txt" original="192.168.0.1" destination="192.168.0.2">
<header>
<tool id="com.apple.TextEdit" name="TextEdit" version="14.0" build="123ABC"/>
</header>
<body>
<item id="item-id-01" xml:space="preserve">
<original>item-id-01</original>
<destination>output from custom function</destination> // <--- custom text
<note>Notes: no notes recorded</note>
</item>
</body>
</file>
<file file-location="Local/Folder/file-b.txt" original="192.168.10.1" destination="192.168.10.2">
<header>
<tool id="com.apple.TextEdit" name="TextEdit" version="14.0" build="123ABC"/>
</header>
<body>
<item id="item-id-02" xml:space="preserve">
<original>item-id-02</original>
<destination>output from custom function</destination> // <--- custom text
<note>Notes: no notes recorded</note>
</item>
</body>
</file>
</data>
当我使用 XMLParserDelegate 时,我能够将所有文本提取到模型数组中:<original>
Item()
struct Item {
var original: String
var destination: String?
var note: String
}
然后进入一个 String 数组,这样我就可以把它传递给我的函数:compactMap
Item.original
let items: [Item] = []
let original: [String] = []
init() {
items = XMLParser.getDataFrom(url: ...)
orignal = items.compactMap({ $0.original })
}
func doThings(_ string: [String]) -> [String] { ... }
let output = doThings(original)
但是,我如何将原始XML文档注入到新文件中,并实质上“另存为......”呢?
我尝试过的事情
将整个 XML 文档添加到它们自己的结构模型中,并遍历所有这些模型以重新构建
- 这对我不起作用,因为我无法将属性导入模型并按原样输出
- 例如。 到
<file file-location="Local/Folder/file-a.txt" original="192.168.0.1" destination="192.168.0.2">
struct File { var header: Header var body: Body var atributes: [String : String] }
将 XML 转换为字符串,找到所有 并将其替换为
</original>
</original><destination>loopValue[index]</destination>
这不起作用,因为如果原始 XML 文档中已经有一个,那么我最终会得到
<destination>
</original><destination>loopValue[index]</destination><destination>.. original document data</destination>
我是没有使用正确的 API,还是有没有实现此结果的好方法?
答:
如果你坚持
无需使用库
剩下的唯一选择是. 是一个低级的 Api,所以使用它并不是很有趣。libxml2
libxml2
C
因为会有另一种选择,但因为你被困住了.macOs
XMLDocument
ios
XMLParser
评论
libxml2
下面是如何使用 XMLDocument 读取和更新 xml 的基本版本。请注意,我们在这里只处理类,所以一切都是通过引用的,这使得更新部分更简单一些。
let document = try! XMLDocument(xmlString: xmlString) //Change this to a suitable init
let nodes = try! document.nodes(forXPath: "/data/file/body/item")
for node in nodes {
if var item = node as? XMLElement {
let element = XMLNode.element(withName: "destination", stringValue: "some string value") as! XMLNode
item.addChild(element)
}
}
然后使用 or 提取并保存修改后的 xmldocument.xmlData
document.xmlString
而且你不应该像我在这里所做的那样到处使用try!
:)
评论
addChild
insertChild