XML仅显示Swift中数组的最后一项

时间:2018-04-09 16:39:28

标签: arrays swift xml parsing

以下是我拥有的XML文件的示例。我解析了所有内容,但无法让数组显示所有项目。

<dish>
    <title> Pancakes </title>
    <calories> 350 calories </calories>
    <ingredients>
        <item>ingredient 1</item>
        <item>ingredient 2</item>
        <item>ingredient 3</item>
    </ingredients>
</dish>

我有食谱结构和成分结构。这些成分只有一个变量&#34; item&#34;在里面。我删除了一些配方代码以包含解析代码的成分部分,因为其他所有工作和打印。

struct Ingredients {
   var item = ""
}

var tableViewDataSource = [Recipes]()
var tableViewIngSource = [Ingredients]()

 func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String] = [:]) {
    thisName = elementName

    // elementName == "recipe" code

    if elementName == "ingredients" {
        var recipeItem = ""
    }

}

func parser(_ parser: XMLParser, foundCharacters string: String) {

    let data = string.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)

    if data.count != 0 {
        switch thisName
        {
        case "title": recipeTitle = data
        case "calories": recipeCalories = data
        case "ingredients": recipeIngredients = data
        case "item": recipeItem = data
        default:
            break
        }
    }
}

func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {
    if elementName == "dish" {
        var recipe = Recipes()
        recipe.title = recipeTitle
        recipe.duration = recipeDuration
        recipe.calories = recipeCalories
        recipe.ingredients = recipeIngredients
        recipe.description = recipeDescription

        //print(recipe)
        tableViewDataSource.append(recipe)

    }

    if elementName == "ingredients" {
        var ingredients = Ingredients()
        ingredients.item = recipeItem

        for item in tableViewIngSource {
            print(item)
        }

        print(ingredients)
        print(tableViewIngSource.count)
        tableViewIngSource.append(ingredients)
    }
}

这是输出。它导致最后两个print语句输出,for循环不打印任何内容

Ingredients(item: "ingredient 3")
0

从我所见,需要使用自定义XML解析器。我已经查看了SWXMLHash,但似乎XML代码需要在swift文件中

1 个答案:

答案 0 :(得分:0)

您的代码需要进行大量重组才能正确解析XML数据。

以下内容更像您想要的内容:

你的食谱结构(注意它是食谱,而不是食谱,因为它代表一个食谱):

struct Recipe {
    let title: String
    let calories: String
    let ingredients: [String]
}

您的解析代码:

var currentText: String?
var recipeTitle: String?
var recipeCalories: String?
var recipeIngredients: [String]?

var tableViewDataSource = [Recipe]()

func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String] = [:]) {
    switch elementName {
    case "dish":
        recipeTitle = nil
        recipeCalories = nil
        recipeIngredients = nil
    case "ingredients":
        recipeIngredients = []
    case "title", "calories", "item":
        currentText = ""
    default:
        break
    }
}

func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {
    switch elementName {
    case "dish":
        if let recipeTitle = recipeTitle, let recipeCalories = recipeCalories, let recipeIngredients = recipeIngredients {
            let recipe = Recipe(title: recipeTitle, calories: recipeCalories, ingredients: recipeIngredients)
            tableViewDataSource.append(recipe)
        }
        recipeTitle = nil
        recipeCalories = nil
        recipeIngredients = nil
    case "title":
        recipeTitle = currentText?.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)
        currentText = nil
    case "calories":
        recipeCalories = currentText?.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)
        currentText = nil
    case "item":
        if let currentText = currentText {
            recipeIngredients?.append(currentText.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines))
        }
        currentText = nil
    default:
        break
    }
}

func parser(_ parser: XMLParser, foundCharacters string: String) {
    currentText?.append(string)
}