Exemplo n.º 1
0
def addetree2xnd(ns, node, elements):
    # Iterate through the tree and collect which elements are encountered and how they are nested
    for path in iterpath(node):
        node = path[-1]
        if "Element" in type(node).__name__:
            (xmlns, name) = getelementname(node)
            if (xmlns, name) in ns.elements:
                xndnode = ns.elements[(xmlns, name)]
            else:
                xndnode = xnd.Element(xmlns, name)
                ns += xndnode
                elements[(xmlns, name)] = set()
            for attrname in list(node.keys()):
                if not attrname.startswith(
                        "{") and attrname not in xndnode.attrs:
                    xndnode += xnd.Attr(attrname, type=xsc.TextAttr)
        elif "ProcessingInstruction" in type(node).__name__:
            name = node.target
            if name not in ns.procinsts:
                ns += xnd.ProcInst(name)
        elif "Comment" in type(node).__name__:
            xndnode = "#comment"
        elif isinstance(node, str):
            if node.isspace():
                xndnode = "#whitespace"
            else:
                xndnode = "#text"
        if len(path) >= 2:
            parent = path[-2]
            if "Element" in type(parent).__name__:
                parententry = elements[getelementname(parent)]
                parententry.add(xndnode)
Exemplo n.º 2
0
 def asxnd(self, model="simple"):
     isrequired = False
     node = misc.first(self[required], None)
     if node is not None:
         value = str(node).strip()
         if value in ("true", "yes"):
             isrequired = True
         elif value not in ("false", "no"):
             raise ValueError(
                 f"value {value!r} not allowed for tag <required>")
     return xnd.Attr(str(self[name][0].content), "xsc.TextAttr", isrequired)
Exemplo n.º 3
0
def adddtd2xnd(ns, dtd):
    # Appends DTD information from :obj:`dtd` to the :class:`xnd.Module` object
    from lxml import etree  # This requires lxml (http://lxml.de/)
    dtd = etree.DTD(dtd)

    # try to guess the namespace name from the dtd
    xmlns = getxmlns(dtd)
    if len(xmlns) == 1:
        xmlns = next(iter(xmlns))
    else:
        xmlns = None

    namegetter = operator.attrgetter("name")
    # Add element info
    elements = sorted(dtd.iterelements(), key=namegetter)
    for elemdecl in elements:
        e = xnd.Element(xmlns, elemdecl.name)

        # Add attribute info for this element
        attrs = sorted(elemdecl.iterattributes(), key=namegetter)
        for attrdecl in attrs:
            if attrdecl.name == "xmlns" or attrdecl.prefix:
                continue  # skip namespace declarations and global attributes
            values = []
            if attrdecl.type == "id":
                type = "xsc.IDAttr"
            else:
                type = "xsc.TextAttr"
                values = attrdecl.values()
                if len(values) == 1:
                    type = "xsc.BoolAttr"
                    values = None
                elif not values:
                    values = None
            default = attrdecl.default_value
            if attrdecl.default == "required":
                required = True
            else:
                required = None
            e += xnd.Attr(name=attrdecl.name,
                          type=type,
                          default=default,
                          required=required,
                          values=values)
        ns += e

    # Iterate through the elements a second time and add model information
    for elemdecl in elements:
        if elemdecl.type == "empty":
            modeltype = "sims.Empty"
            modelargs = None
        elif elemdecl.type == "any":
            modeltype = "sims.Any"
            modelargs = None
        else:

            def extractcont(model):
                content = set()
                if model is not None:
                    content.update(extractcont(model.left))
                    if model.name is not None:
                        content.add(model.name)
                    content.update(extractcont(model.right))
                return content

            elementcontent = extractcont(elemdecl.content)
            if elementcontent:
                modelargs = [
                    ns.elements[(xmlns, name)] for name in elementcontent
                ]
                if elemdecl.type == "mixed":
                    modeltype = "sims.ElementsOrText"
                else:
                    modeltype = "sims.Elements"
            else:
                modelargs = []
                if elemdecl.type == "mixed":
                    modeltype = "sims.NoElements"
                else:
                    modeltype = "sims.NoElementsOrText"
        e = ns.elements[(xmlns, elemdecl.name)]
        if ns.model == "simple":
            modeltype = modeltype == "sims.Empty"
            modelargs = None
        e.modeltype = modeltype
        e.modelargs = modelargs

    # Add entities
    entities = sorted(dtd.iterentities(), key=namegetter)
    for entdecl in entities:
        if entdecl.name not in ("quot", "apos", "gt", "lt",
                                "amp") and entdecl.content and len(
                                    entdecl.content) == 1:
            ns += xnd.CharRef(entdecl.name, codepoint=ord(entdecl.content))