Next / Previous / Contents / Shipman's homepage

10.4. Loc.readNode(): Convert from XML (static method)

This method reconstructs the node element and its children.

birdnotes.py
# - - -   L o c . r e a d N o d e

    @staticmethod
    def readNode(node):
        """Convert XML to a Loc instance.
        """

First we'll create a new Loc instance with attribute values taken from the node. See Section 10.1, “Loc.__init__(): Constructor”.

birdnotes.py
        #-- 1 --
        # [ code  :=  rnc.CODE_A attribute from node
        #   name  :=  rnc.NAME_A attribute from node ]
        code = node.attrib[rnc.CODE_A]
        name = node.attrib[rnc.NAME_A]

        #-- 2 --
        # [ loc  :=  a new Loc instance with code=(code) and
        #            name=(name) and no text ]
        loc = Loc(code, name)

Next we look to see if there are any gps children and, if so, make them into Gps instances and add them to the Loc instance. See Section 11.2, “Gps.readNode() (static method)”.

birdnotes.py
        #-- 3 --
        # [ gpsNodeList  :=  a list containing all rnc.GPS_N
        #                    children of node
        #   lastGps  :=  None ]
        gpsNodeList = node.xpath(rnc.GPS_N)

        #-- 4 --
        # [ if gpsNodeList is non-empty ->
        #     loc  :=  loc with Gps instances added, made from
        #              elements of gpsNodeList
        #     lastGps  :=  the last Gps instance added
        #   else -> I ]
        for  gpsNode in gpsNodeList:
            lastGps = Gps.readNode(gpsNode)
            loc.addGps(lastGps)

Next we check for the optional narrative describing the location. To get around the strange way lxml handles text, we'll use the XPath expression "text()" to get a list of all the text node children of node, which we will then concatenate. If any of the gps element children have text nodes, they will not be included. The .strip() method will delete leading and trailing space, and if there is nothing left, we consider that no narrative.

birdnotes.py
        #-- 5 --
        # [ if  (node has any nonblank text children) and
        #   (lastGps is None) ->
        #     loc.text  :=  all text children, minus leading and
        #                   trailing space
        #   else if node has any nonblank text children ->
        #     lastGps.tail  :=  all text children, minus leading
        #                       and trailing space
        #   else -> I ]
        textList = node.xpath('text()')
        s = "".join(textList).strip()
        if  s:
            loc.text = s

All that remains is to return the newly built Loc instance.

birdnotes.py
        #-- 6 --
        return  loc