0
votes

How can I, in a NSOutlineView, binded to a NSTreeController, driven by an NSXMLDocument, only display some NSElements (of the same type) and not others?

Thanks

1
The treeController is the datasource, so you have to make sure the treeController's content is the subset you want. So what have you tried that's not working?stevesliva
@stevesliva I don't want to remove the elements from the content. I just want them to don't be displayed.João Colaço
You may have to explain why your tree controller can't just use a subset and must use everything... It's the most straightforward way to go about it. Trying to implement delegate functions to test the object type gets hokey because rows can't be 0 height and must be displayedstevesliva
@stevesilva The XML that I'm using shouldn't be modified. It's a public available file with an alphabetic list of diagnosis and their ICD10 codes and has a yearly release with the same format. The problem, to me, it's that on the file the names of the diseases and their codes are contents of XML elements. The problem could be solved converting the elements to attributes, but then I won't be working with the original file.João Colaço

1 Answers

0
votes

To hide some elements the NSXMLElement has to be subclassed. The aim it's to test if one of the children of an element it's one of the ones to be hidden and remove it from the children array:

class ICoderElement:NSXMLElement{

    ///List of elements names to remove
    let nodeElementsNamesToRemove = ["title", "code"]

    override var children: [AnyObject]? {

        //get the array with all the children
        var superChildren = super.children

        //Cast the array of children to its true self
        if var trueSuperChildren = superChildren as? [NSXMLNode] {

            //Test if the array isn't empty to don't iterate over it
            if trueSuperChildren.count > 0 {

                //Iterate each of them
                for var index = 0; index < trueSuperChildren.count; index++ {
                    let node = trueSuperChildren[index]

                    //If any it's of NSXMLElement class unwarps it's name and...
                    if let nodeElement = node as? NSXMLElement, let nodeName = nodeElement.name {

                        //..tests if it's name it's o the list of elements to remove
                        //change to nodeElementsNamesToRemove.contains(nodeName) in swift2
                        if contains(nodeElementsNamesToRemove, nodeName) {

                            //Remove the child NSXMLElement from the array
                            trueSuperChildren.removeAtIndex(index)

                            //reduce the index as the array 1 less element
                            index = index - 1
                        }
                    }
                }
            }
            //returns the array without the selected elements
            return trueSuperChildren
        }
        return superChildren
    }
}

To use this class the NSXMLDocument has also to be subclassed so it can replaced with NSXMLElement:

class ICoderXMLDocument:NSXMLDocument {
    override class func replacementClassForClass(cls: AnyClass) -> AnyClass! {

        //Replace NSXMLElement by ICoderElement
        if cls === NSXMLElement.self {

            return ICoderElement.self
        }
        return cls
    }
}

From now on childCount should be used carefully. It will still return the number of child nodes from the XML file.

Because those elements are only hidden the still can be of with functions like elementsForName.