Changeset 28164 in vbox
- Timestamp:
- Apr 11, 2010 5:55:37 PM (15 years ago)
- svn:sync-xref-src-repo-rev:
- 59896
- Location:
- trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/iprt/cpp/xml.h
r28163 r28164 467 467 xmlNode *m_plibNode; // != NULL if this is an element or content node 468 468 xmlAttr *m_plibAttr; // != NULL if this is an attribute node 469 const char *m_pcszNamespace; 469 const char *m_pcszNamespacePrefix; // not always set 470 const char *m_pcszNamespaceHref; // full http:// spec 470 471 const char *m_pcszName; // element or attribute name, points either into plibNode or plibAttr; 471 472 // NULL if this is a content node … … 478 479 Node(const Node &x); // no copying 479 480 480 void buildChildren( );481 void buildChildren(const ElementNode &elmRoot); 481 482 482 483 /* Obscure class data */ 483 484 struct Data; 484 485 Data *m; 486 487 friend class AttributeNode; 485 488 }; 486 489 … … 530 533 protected: 531 534 // hide the default constructor so people use only our factory methods 532 ElementNode( Node *pParent, xmlNode *plibNode);535 ElementNode(const ElementNode *pelmRoot, Node *pParent, xmlNode *plibNode); 533 536 ElementNode(const ElementNode &x); // no copying 537 538 const ElementNode *m_pelmRoot; 534 539 535 540 friend class Node; … … 557 562 protected: 558 563 // hide the default constructor so people use only our factory methods 559 AttributeNode(Node *pParent, xmlAttr *plibAttr); 564 AttributeNode(const ElementNode &elmRoot, 565 Node *pParent, 566 xmlAttr *plibAttr, 567 const char **ppcszKey); 560 568 AttributeNode(const AttributeNode &x); // no copying 569 570 iprt::MiniString m_strKey; 561 571 562 572 friend class Node; -
trunk/src/VBox/Runtime/r3/xml.cpp
r28163 r28164 445 445 m_plibNode(plibNode), 446 446 m_plibAttr(plibAttr), 447 m_pcszNamespace(NULL), 447 m_pcszNamespacePrefix(NULL), 448 m_pcszNamespaceHref(NULL), 448 449 m_pcszName(NULL), 449 450 m(new Data) … … 456 457 } 457 458 458 void Node::buildChildren( ) // private459 void Node::buildChildren(const ElementNode &elmRoot) // private 459 460 { 460 461 // go thru this element's attributes … … 462 463 while (plibAttr) 463 464 { 464 const char *pcsz AttribName = (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)); 466 467 // store 467 m->attribs[pcsz AttribName] = pNew;468 m->attribs[pcszKey] = pNew; 468 469 469 470 plibAttr = plibAttr->next; … … 477 478 478 479 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)); 480 481 else if (plibNode->type == XML_TEXT_NODE) 481 482 pNew = boost::shared_ptr<Node>(new ContentNode(this, plibNode)); … … 486 487 487 488 // recurse for this child element to get its own children 488 pNew->buildChildren( );489 pNew->buildChildren(elmRoot); 489 490 } 490 491 … … 519 520 return true; 520 521 // caller wants namespace: 521 if (!m_pcszNamespace )522 if (!m_pcszNamespacePrefix) 522 523 // but node has no namespace: 523 524 return false; 524 return !strcmp(m_pcszNamespace , pcszNamespace);525 return !strcmp(m_pcszNamespacePrefix, pcszNamespace); 525 526 } 526 527 … … 629 630 } 630 631 631 ElementNode::ElementNode(Node *pParent, xmlNode *plibNode) 632 ElementNode::ElementNode(const ElementNode *pelmRoot, 633 Node *pParent, 634 xmlNode *plibNode) 632 635 : Node(IsElement, 633 636 pParent, … … 635 638 NULL) 636 639 { 640 if (!(m_pelmRoot = pelmRoot)) 641 // NULL passed, then this is the root element 642 m_pelmRoot = this; 643 637 644 m_pcszName = (const char*)plibNode->name; 638 645 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 } 643 651 } 644 652 … … 735 743 736 744 /** 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. 737 761 * 738 762 * @param pcszMatch … … 754 778 * name and returns its value as a string. 755 779 * 756 * @param pcszMatch name of attribute to find .780 * @param pcszMatch name of attribute to find (see findAttribute() for namespace remarks) 757 781 * @param ppcsz out: attribute value 758 782 * @return TRUE if attribute was found and str was thus updated. … … 774 798 * name and returns its value as a string. 775 799 * 776 * @param pcszMatch name of attribute to find .800 * @param pcszMatch name of attribute to find (see findAttribute() for namespace remarks) 777 801 * @param str out: attribute value; overwritten only if attribute was found 778 802 * @return TRUE if attribute was found and str was thus updated. … … 796 820 * function returns no error. 797 821 * 798 * @param pcszMatch name of attribute to find .822 * @param pcszMatch name of attribute to find (see findAttribute() for namespace remarks) 799 823 * @param i out: attribute value; overwritten only if attribute was found 800 824 * @return TRUE if attribute was found and str was thus updated. … … 817 841 * function returns no error. 818 842 * 819 * @param pcszMatch name of attribute to find .843 * @param pcszMatch name of attribute to find (see findAttribute() for namespace remarks) 820 844 * @param i out: attribute value; overwritten only if attribute was found 821 845 * @return TRUE if attribute was found and str was thus updated. … … 838 862 * function returns no error. 839 863 * 840 * @param pcszMatch name of attribute to find .864 * @param pcszMatch name of attribute to find (see findAttribute() for namespace remarks) 841 865 * @param i out: attribute value 842 866 * @return TRUE if attribute was found and str was thus updated. … … 859 883 * function returns no error. 860 884 * 861 * @param pcszMatch name of attribute to find .885 * @param pcszMatch name of attribute to find (see findAttribute() for namespace remarks) 862 886 * @param i out: attribute value; overwritten only if attribute was found 863 887 * @return TRUE if attribute was found and str was thus updated. … … 879 903 * "yes", "no", "1" or "0" as valid values. 880 904 * 881 * @param pcszMatch name of attribute to find .905 * @param pcszMatch name of attribute to find (see findAttribute() for namespace remarks) 882 906 * @param f out: attribute value; overwritten only if attribute was found 883 907 * @return TRUE if attribute was found and str was thus updated. … … 930 954 931 955 // now wrap this in C++ 932 ElementNode *p = new ElementNode( this, plibNode);956 ElementNode *p = new ElementNode(m_pelmRoot, this, plibNode); 933 957 boost::shared_ptr<ElementNode> pNew(p); 934 958 m->children.push_back(pNew); … … 981 1005 // libxml side: xmlNewProp creates an attribute 982 1006 xmlAttr *plibAttr = xmlNewProp(m_plibNode, (xmlChar*)pcszName, (xmlChar*)pcszValue); 983 const char *pcszAttribName = (const char*)plibAttr->name;984 1007 985 1008 // 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)); 987 1011 // store 988 m->attribs[pcsz AttribName] = pNew;1012 m->attribs[pcszKey] = pNew; 989 1013 } 990 1014 else … … 1048 1072 } 1049 1073 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 */ 1084 AttributeNode::AttributeNode(const ElementNode &elmRoot, 1085 Node *pParent, 1086 xmlAttr *plibAttr, 1087 const char **ppcszKey) 1051 1088 : Node(IsAttribute, 1052 1089 pParent, … … 1055 1092 { 1056 1093 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 } 1057 1116 } 1058 1117 … … 1191 1250 void Document::refreshInternals() // private 1192 1251 { 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); 1196 1255 } 1197 1256 … … 1234 1293 1235 1294 // now wrap this in C++ 1236 m->pRootElement = new ElementNode(NULL, plibRootNode);1295 m->pRootElement = new ElementNode(NULL, NULL, plibRootNode); 1237 1296 1238 1297 return m->pRootElement;
Note:
See TracChangeset
for help on using the changeset viewer.