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