Skip to content

Instantly share code, notes, and snippets.

@lsloan
Created October 26, 2021 18:08
Show Gist options
  • Save lsloan/1992bf3d65ed9a4c2ceefb372b6ab489 to your computer and use it in GitHub Desktop.
Save lsloan/1992bf3d65ed9a4c2ceefb372b6ab489 to your computer and use it in GitHub Desktop.
pyslet QTI example: traversing a parsed tree
from typing import Optional, Any, Sequence
import pyslet.qtiv2.xml as qti
from pyslet.xml.namespace import NSElement
from pyslet.xml.structures import Document, Element
def getChildElements(node: NSElement) -> Sequence[NSElement]:
# skips strings not enclosed within elements (e.g., linebreaks in XML file)
return [child for child in node.get_children() if
isinstance(child, NSElement)]
def getAttr(node: NSElement, attrName: str, default: Any = None) -> \
Optional[Any]:
# gracefully return attribute value or substitute a default value
try:
return node.get_attribute(attrName)
except KeyError:
return default
def traverseChildTree(node: NSElement, depth=0, indentSize=2) -> None:
children = getChildElements(node)
if len(children) == 0:
return
indentation = ' ' * depth * indentSize
for child in children:
interestingAttributes = ['title', 'ident', 'respident']
interestingAttrValues = {key: getAttr(child, key) for key in
interestingAttributes if getAttr(child, key)}
print(indentation + '; '.join([
f'<{child.xmlname}>',
f'attributes: {interestingAttrValues}',
# ignore values that contain other elements,
# those elements will be seen when traversing the next level
f'value: "{child.get_value(ignore_elements=True).strip()}"']))
traverseChildTree(child, depth=depth + 1)
if '__main__' == __name__:
doc = qti.QTIDocument()
with open('sample-test.xml', 'rb') as f:
doc.read(src=f)
root: Document = doc.root
traverseChildTree(root)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment