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
GetFirstDescriptionElement(const xmlDocPtr parent)12 xmlNodePtr GetFirstDescriptionElement(const xmlDocPtr parent) {
13 return DepthFirstSearch(parent, XmlConst::RdfDescription());
14 }
15
GetFirstSeqElement(xmlDocPtr parent)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.
GetFirstSeqElement(xmlNodePtr parent)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.
GetElementAt(xmlNodePtr node,int index)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
GetLiNodeContent(xmlNodePtr node)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
XmlDocToString(const xmlDocPtr doc)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