1 #include "xmpmeta/xml/utils.h" 2 3 #include "android-base/logging.h" 4 #include "base/port.h" 5 #include "xmpmeta/xml/const.h" 6 #include "xmpmeta/xml/search.h" 7 8 namespace dynamic_depth { 9 namespace xmpmeta { 10 namespace xml { 11 12 xmlNodePtr GetFirstDescriptionElement(const xmlDocPtr parent) { 13 return DepthFirstSearch(parent, XmlConst::RdfDescription()); 14 } 15 16 xmlNodePtr GetFirstSeqElement(xmlDocPtr parent) { 17 // DepthFirstSearch will perform the null check. 18 return DepthFirstSearch(parent, XmlConst::RdfSeq()); 19 } 20 21 // Returns the first rdf:Seq element found in the given node. 22 xmlNodePtr GetFirstSeqElement(xmlNodePtr parent) { 23 // DepthFirstSearch will perform the null check. 24 return DepthFirstSearch(parent, XmlConst::RdfSeq()); 25 } 26 27 // Returns the ith (zero-indexed) element in the given node. 28 // {@code parent} is an rdf:Seq node. 29 xmlNodePtr GetElementAt(xmlNodePtr node, int index) { 30 if (node == nullptr || index < 0) { 31 LOG(ERROR) << "Node was null or index was negative"; 32 return nullptr; 33 } 34 const string node_name = FromXmlChar(node->name); 35 if (strcmp(node_name.c_str(), XmlConst::RdfSeq())) { 36 LOG(ERROR) << "Node is not an rdf:Seq node, was " << node_name; 37 return nullptr; 38 } 39 int i = 0; 40 for (xmlNodePtr child = node->children; child != nullptr && i <= index; 41 child = child->next) { 42 if (strcmp(FromXmlChar(child->name), XmlConst::RdfLi())) { 43 // This is not an rdf:li node. This can occur because the node's content 44 // is also treated as a node, and these should be ignored. 45 continue; 46 } 47 if (i == index) { 48 return child; 49 } 50 i++; 51 } 52 return nullptr; 53 } 54 55 const string GetLiNodeContent(xmlNodePtr node) { 56 string value; 57 if (node == nullptr || strcmp(FromXmlChar(node->name), XmlConst::RdfLi())) { 58 LOG(ERROR) << "Node is null or is not an rdf:li node"; 59 return value; 60 } 61 xmlChar* node_content = xmlNodeGetContent(node); 62 value = FromXmlChar(node_content); 63 free(node_content); 64 return value; 65 } 66 67 const string XmlDocToString(const xmlDocPtr doc) { 68 xmlChar* xml_doc_contents; 69 int doc_size = 0; 70 xmlDocDumpFormatMemoryEnc(doc, &xml_doc_contents, &doc_size, 71 XmlConst::EncodingStr(), 1); 72 const string xml_doc_string(FromXmlChar(xml_doc_contents)); 73 xmlFree(xml_doc_contents); 74 return xml_doc_string; 75 } 76 77 } // namespace xml 78 } // namespace xmpmeta 79 } // namespace dynamic_depth 80