VirtualBox

Ignore:
Timestamp:
Apr 11, 2010 5:55:37 PM (15 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
59896
Message:

IPRT: attribute namespace support

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/r3/xml.cpp

    r28163 r28164  
    445445      m_plibNode(plibNode),
    446446      m_plibAttr(plibAttr),
    447       m_pcszNamespace(NULL),
     447      m_pcszNamespacePrefix(NULL),
     448      m_pcszNamespaceHref(NULL),
    448449      m_pcszName(NULL),
    449450      m(new Data)
     
    456457}
    457458
    458 void Node::buildChildren()       // private
     459void Node::buildChildren(const ElementNode &elmRoot)       // private
    459460{
    460461    // go thru this element's attributes
     
    462463    while (plibAttr)
    463464    {
    464         const char *pcszAttribName = (const char*)plibAttr->name;
    465         boost::shared_ptr<AttributeNode> pNew(new AttributeNode(this, plibAttr));
     465        const char *pcszKey;
     466        boost::shared_ptr<AttributeNode> pNew(new AttributeNode(elmRoot, this, plibAttr, &pcszKey));
    466467        // store
    467         m->attribs[pcszAttribName] = pNew;
     468        m->attribs[pcszKey] = pNew;
    468469
    469470        plibAttr = plibAttr->next;
     
    477478
    478479        if (plibNode->type == XML_ELEMENT_NODE)
    479             pNew = boost::shared_ptr<Node>(new ElementNode(this, plibNode));
     480            pNew = boost::shared_ptr<Node>(new ElementNode(&elmRoot, this, plibNode));
    480481        else if (plibNode->type == XML_TEXT_NODE)
    481482            pNew = boost::shared_ptr<Node>(new ContentNode(this, plibNode));
     
    486487
    487488            // recurse for this child element to get its own children
    488             pNew->buildChildren();
     489            pNew->buildChildren(elmRoot);
    489490        }
    490491
     
    519520        return true;
    520521    // caller wants namespace:
    521     if (!m_pcszNamespace)
     522    if (!m_pcszNamespacePrefix)
    522523        // but node has no namespace:
    523524        return false;
    524     return !strcmp(m_pcszNamespace, pcszNamespace);
     525    return !strcmp(m_pcszNamespacePrefix, pcszNamespace);
    525526}
    526527
     
    629630}
    630631
    631 ElementNode::ElementNode(Node *pParent, xmlNode *plibNode)
     632ElementNode::ElementNode(const ElementNode *pelmRoot,
     633                         Node *pParent,
     634                         xmlNode *plibNode)
    632635    : Node(IsElement,
    633636           pParent,
     
    635638           NULL)
    636639{
     640    if (!(m_pelmRoot = pelmRoot))
     641        // NULL passed, then this is the root element
     642        m_pelmRoot = this;
     643
    637644    m_pcszName = (const char*)plibNode->name;
    638645
    639     if (    plibNode->ns
    640          && plibNode->ns->prefix
    641        )
    642         m_pcszNamespace = (const char*)m_plibNode->ns->prefix;
     646    if (plibNode->ns)
     647    {
     648        m_pcszNamespacePrefix = (const char*)m_plibNode->ns->prefix;
     649        m_pcszNamespaceHref = (const char*)m_plibNode->ns->href;
     650    }
    643651}
    644652
     
    735743
    736744/**
     745 * Looks up the given attribute node in this element's attribute map.
     746 *
     747 * With respect to namespaces, the internal attributes map stores namespace
     748 * prefixes with attribute names only if the attribute uses a non-default
     749 * namespace. As a result, the following rules apply:
     750 *
     751 *  -- To find attributes from a non-default namespace, pcszMatch must not
     752 *     be prefixed with a namespace.
     753 *
     754 *  -- To find attributes from the default namespace (or if the document does
     755 *     not use namespaces), pcszMatch must be prefixed with the namespace
     756 *     prefix and a colon.
     757 *
     758 * For example, if the document uses the "vbox:" namespace by default, you
     759 * must omit "vbox:" from pcszMatch to find such attributes, whether they
     760 * are specifed in the xml or not.
    737761 *
    738762 * @param pcszMatch
     
    754778 * name and returns its value as a string.
    755779 *
    756  * @param pcszMatch name of attribute to find.
     780 * @param pcszMatch name of attribute to find (see findAttribute() for namespace remarks)
    757781 * @param ppcsz out: attribute value
    758782 * @return TRUE if attribute was found and str was thus updated.
     
    774798 * name and returns its value as a string.
    775799 *
    776  * @param pcszMatch name of attribute to find.
     800 * @param pcszMatch name of attribute to find (see findAttribute() for namespace remarks)
    777801 * @param str out: attribute value; overwritten only if attribute was found
    778802 * @return TRUE if attribute was found and str was thus updated.
     
    796820 * function returns no error.
    797821 *
    798  * @param pcszMatch name of attribute to find.
     822 * @param pcszMatch name of attribute to find (see findAttribute() for namespace remarks)
    799823 * @param i out: attribute value; overwritten only if attribute was found
    800824 * @return TRUE if attribute was found and str was thus updated.
     
    817841 * function returns no error.
    818842 *
    819  * @param pcszMatch name of attribute to find.
     843 * @param pcszMatch name of attribute to find (see findAttribute() for namespace remarks)
    820844 * @param i out: attribute value; overwritten only if attribute was found
    821845 * @return TRUE if attribute was found and str was thus updated.
     
    838862 * function returns no error.
    839863 *
    840  * @param pcszMatch name of attribute to find.
     864 * @param pcszMatch name of attribute to find (see findAttribute() for namespace remarks)
    841865 * @param i out: attribute value
    842866 * @return TRUE if attribute was found and str was thus updated.
     
    859883 * function returns no error.
    860884 *
    861  * @param pcszMatch name of attribute to find.
     885 * @param pcszMatch name of attribute to find (see findAttribute() for namespace remarks)
    862886 * @param i out: attribute value; overwritten only if attribute was found
    863887 * @return TRUE if attribute was found and str was thus updated.
     
    879903 * "yes", "no", "1" or "0" as valid values.
    880904 *
    881  * @param pcszMatch name of attribute to find.
     905 * @param pcszMatch name of attribute to find (see findAttribute() for namespace remarks)
    882906 * @param f out: attribute value; overwritten only if attribute was found
    883907 * @return TRUE if attribute was found and str was thus updated.
     
    930954
    931955    // now wrap this in C++
    932     ElementNode *p = new ElementNode(this, plibNode);
     956    ElementNode *p = new ElementNode(m_pelmRoot, this, plibNode);
    933957    boost::shared_ptr<ElementNode> pNew(p);
    934958    m->children.push_back(pNew);
     
    9811005        // libxml side: xmlNewProp creates an attribute
    9821006        xmlAttr *plibAttr = xmlNewProp(m_plibNode, (xmlChar*)pcszName, (xmlChar*)pcszValue);
    983         const char *pcszAttribName = (const char*)plibAttr->name;
    9841007
    9851008        // C++ side: create an attribute node around it
    986         boost::shared_ptr<AttributeNode> pNew(new AttributeNode(this, plibAttr));
     1009        const char *pcszKey;
     1010        boost::shared_ptr<AttributeNode> pNew(new AttributeNode(*m_pelmRoot, this, plibAttr, &pcszKey));
    9871011        // store
    988         m->attribs[pcszAttribName] = pNew;
     1012        m->attribs[pcszKey] = pNew;
    9891013    }
    9901014    else
     
    10481072}
    10491073
    1050 AttributeNode::AttributeNode(Node *pParent, xmlAttr *plibAttr)
     1074/**
     1075 * Private constructur for a new attribute node. This one is special:
     1076 * in ppcszKey, it returns a pointer to a string buffer that should be
     1077 * used to index the attribute correctly with namespaces.
     1078 *
     1079 * @param pParent
     1080 * @param elmRoot
     1081 * @param plibAttr
     1082 * @param ppcszKey
     1083 */
     1084AttributeNode::AttributeNode(const ElementNode &elmRoot,
     1085                             Node *pParent,
     1086                             xmlAttr *plibAttr,
     1087                             const char **ppcszKey)
    10511088    : Node(IsAttribute,
    10521089           pParent,
     
    10551092{
    10561093    m_pcszName = (const char*)plibAttr->name;
     1094
     1095    *ppcszKey = m_pcszName;
     1096
     1097    if (    plibAttr->ns
     1098         && plibAttr->ns->prefix
     1099       )
     1100    {
     1101        m_pcszNamespacePrefix = (const char*)plibAttr->ns->prefix;
     1102        m_pcszNamespaceHref = (const char*)plibAttr->ns->href;
     1103
     1104        if (    !elmRoot.m_pcszNamespaceHref
     1105             || (strcmp(m_pcszNamespaceHref, elmRoot.m_pcszNamespaceHref))
     1106           )
     1107        {
     1108            // not default namespace:
     1109            m_strKey = m_pcszNamespacePrefix;
     1110            m_strKey.append(':');
     1111            m_strKey.append(m_pcszName);
     1112
     1113            *ppcszKey = m_strKey.c_str();
     1114        }
     1115    }
    10571116}
    10581117
     
    11911250void Document::refreshInternals() // private
    11921251{
    1193     m->pRootElement = new ElementNode(NULL, xmlDocGetRootElement(m->plibDocument));
    1194 
    1195     m->pRootElement->buildChildren();
     1252    m->pRootElement = new ElementNode(NULL, NULL, xmlDocGetRootElement(m->plibDocument));
     1253
     1254    m->pRootElement->buildChildren(*m->pRootElement);
    11961255}
    11971256
     
    12341293
    12351294    // now wrap this in C++
    1236     m->pRootElement = new ElementNode(NULL, plibRootNode);
     1295    m->pRootElement = new ElementNode(NULL, NULL, plibRootNode);
    12371296
    12381297    return m->pRootElement;
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette