【问题标题】:Very Weird Parsing of unusual xml异常 xml 的非常奇怪的解析
【发布时间】:2019-04-26 12:38:37
【问题描述】:

我在使用 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)如何正确拾取多个内部Text和标签。

感谢您为此提供的帮助。我真的希望有一个解决方案。

约瑟夫

【问题讨论】:

    标签: swift xml xmlmapper


    【解决方案1】:

    您可以参考XMLMapper存储库中的this问题

    因为src 元素有时包含多个文本部分(innerText),所以您必须像Array&lt;String&gt; 一样映射它(同样适用于src 内部的w 元素)

    因此,您可以尝试将 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
    

    希望对你有帮助

    【讨论】:

    • 感谢您的回答。我会添加这个。我以为我忽略了一些东西。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-07-02
    • 1970-01-01
    • 2020-01-10
    • 1970-01-01
    • 1970-01-01
    • 2012-08-12
    • 2011-10-02
    相关资源
    最近更新 更多