我在使用XMLMappable时遇到问题。这可能是飞行员错误,但3天后我还没有找到它。我已经查看了#xmlmapper的问题/解答,但没有找到任何与此相关的内容。这个问题How to access grand child element?看起来很有希望,但我认为这不是同一问题。如果我错了,请纠正我。
我已经使用XMLMappable编写了XMLParser。我以较小的增量构建了它,直到最后一个解析器(Src)都运行良好。解析器不使用xsd,但是预定义的xsd看起来像:
<xs:complexType name="srcCT" mixed="true">
<xs:choice maxOccurs="unbounded" minOccurs="0">
<xs:element name="w" type="wCT"/>
</xs:choice>
</xs:complexType>
这意味着,如果存在src标记,则可以将0或多个innerText与w标记交替显示,例如:
<src> text <w> wtext </w> more text <w> another w tag </w>...</src>
问题在于解析器结果随处可见,哪些组合有效,哪些无效。
因此,使用示例解析器创建了我的测试和测试数据,并将其添加到此处。请原谅丑陋的印刷线条:
import Foundation
import XMLMapper
class TestParser : XMLMappable
{
var nodeName: String!
var entries: [Entry]?
required init ( map: XMLMap )
{
}
func mapping ( map: XMLMap )
{
entries <- map ["entry"]
}
}
class Entry: XMLMappable
{
var nodeName: String!
var id : String?
var lang : String?
var word : W?
var source : Src?
var teststring : String?
required init ( map: XMLMap )
{
}
func mapping ( map: XMLMap )
{
var raw : String?
raw <- map.attributes [ "id" ]
guard raw != nil else { return }
teststring <- map ["testString"]
if teststring != nil
{
print ( "teststring = " + teststring! )
}
lang = String ( raw?.prefix ( 1 ) ?? "q" )
id = String ( (raw?.dropFirst ( 1 ))!)
print ( "************************** \n entry id = " + raw! )
word <- map ["w"]
source <- map ["src"]
print ( "word = " + (word?.word)! )
}
}
class W: XMLMappable
{
var nodeName: String!
var word : String?
var lang : String?
var src : String?
required init ( map: XMLMap )
{
}
func mapping ( map: XMLMap )
{
lang <- map ["_xml:lang"]
src <- map [ "_src"]
word <- map.innerText
}
}
// The P R O B L E M Child
class Src: XMLMappable
{
var nodeName: String!
var srctext : String?
var references : [W]? = [W] ()
required init ( map: XMLMap )
{
}
func mapping ( map: XMLMap )
{
srctext <- map.innerText
if srctext == nil
{
srctext = "???"
}
var word : W?
word <- map ["w"]
guard word != nil else { return }
references?.append ( word! )
print ( "source.w.reference = " + word!.word! )
print ( "source .srctext = " + (srctext!) )
}
}
=========== 测试数据:
<?xml version="1.0" encoding="utf-8"?>
<lexicon >
<entry id="Q1a">
<testString>Test string Q1</testString>
<w xml:lang="eng">q1</w>
<src>src parser never called for this entry</src>
</entry>
<entry id="Q2">
<w xml:lang="eng">q2</w>
<src>this doesn't (map.innerText returns nil and i change to ???) <w src="Q2a">This works (2a)</w>; never reached </src>
</entry>
<entry id="Q3">
<w xml:lang="eng">q3</w>
<src>map.innerText returns nil <w src="3">This does not work (3)</w>; never reached <w src="Q3a">never reached</w></src>
</entry>
<entry id="Q4">
<w xml:lang="eng">q4</w>
<src>map.innerText returns nil <w src="q4a">This Works: 4a</w>;</src>
</entry>
<entry id="Q5">
<w xml:lang="eng">q5</w>
<src>This works <w src="Q5a">and so does this: 5a</w></src>
</entry>
</lexicon>
==============
和输出:
teststring = Test string Q1
**************************
entry id = Q1a
word = q1
**************************
entry id = Q2
source.w.reference = This works (2a)
source .srctext = return nil
word = q2
**************************
entry id = Q3
word = q3
**************************
entry id = Q4
source.w.reference = This Works: 4a
source .srctext = return nil
word = q4
**************************
entry id = Q5
source.w.reference = and so does this: 5a
source .srctext = This works
word = q5
有两个一般性问题:1)为什么解析器有时会拾取元素,而其他时候却没有。 2)如何正确拾取多个内部文本和标签。
谢谢您的协助。我真的希望有解决方案。
约瑟夫
答案 0 :(得分:0)
由于src
元素有时具有多个部分的文本(innerText),因此必须像Array<String>
一样映射它(内部的w
元素也是如此src
)
因此,您可以尝试将Src
类替换为:
class Src: XMLMappable {
var nodeName: String!
var srctext: [String]?
var references: [W]?
required init(map: XMLMap) {}
func mapping(map: XMLMap) {
srctext <- map.innerText
references <- map["w"]
}
}
即使那样,映射的值也可能不太容易阅读。
例如,将以下元素与上述模型类映射:
<src>
map.innerText returns nil
<w src="3">This does not work (3)</w>
; never reached
<w src="Q3a">never reached</w>
</src>
您最终遇到这样的事情:
// assuming that `source` is the variable in which you mapped the above `src` element
let source: Src = entry.source
// the printed values are in comments
print(source.srctext[0]) // map.innerText returns nil
print(source.srctext[1]) // ; never reached
print(references.references[0].word) // This does not work (3)
print(references.references[1].word) // never reached
希望这会有所帮助