1251876Speter/* Licensed to the Apache Software Foundation (ASF) under one or more 2251876Speter * contributor license agreements. See the NOTICE file distributed with 3251876Speter * this work for additional information regarding copyright ownership. 4251876Speter * The ASF licenses this file to You under the Apache License, Version 2.0 5251876Speter * (the "License"); you may not use this file except in compliance with 6251876Speter * the License. You may obtain a copy of the License at 7251876Speter * 8251876Speter * http://www.apache.org/licenses/LICENSE-2.0 9251876Speter * 10251876Speter * Unless required by applicable law or agreed to in writing, software 11251876Speter * distributed under the License is distributed on an "AS IS" BASIS, 12251876Speter * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13251876Speter * See the License for the specific language governing permissions and 14251876Speter * limitations under the License. 15251876Speter */ 16251876Speter/** 17251876Speter * @file apr_xml.h 18251876Speter * @brief APR-UTIL XML Library 19251876Speter */ 20251876Speter#ifndef APR_XML_H 21251876Speter#define APR_XML_H 22251876Speter 23251876Speter/** 24251876Speter * @defgroup APR_Util_XML XML 25251876Speter * @ingroup APR_Util 26251876Speter * @{ 27251876Speter */ 28251876Speter#include "apr_pools.h" 29251876Speter#include "apr_tables.h" 30251876Speter#include "apr_file_io.h" 31251876Speter 32251876Speter#include "apu.h" 33251876Speter#if APR_CHARSET_EBCDIC 34251876Speter#include "apr_xlate.h" 35251876Speter#endif 36251876Speter 37251876Speter#ifdef __cplusplus 38251876Speterextern "C" { 39251876Speter#endif 40251876Speter 41251876Speter/** 42251876Speter * @package Apache XML library 43251876Speter */ 44251876Speter 45251876Speter/* -------------------------------------------------------------------- */ 46251876Speter 47251876Speter/* ### these will need to move at some point to a more logical spot */ 48251876Speter 49251876Speter/** @see apr_text */ 50251876Spetertypedef struct apr_text apr_text; 51251876Speter 52251876Speter/** Structure to keep a linked list of pieces of text */ 53251876Speterstruct apr_text { 54251876Speter /** The current piece of text */ 55251876Speter const char *text; 56251876Speter /** a pointer to the next piece of text */ 57251876Speter struct apr_text *next; 58251876Speter}; 59251876Speter 60251876Speter/** @see apr_text_header */ 61251876Spetertypedef struct apr_text_header apr_text_header; 62251876Speter 63251876Speter/** A list of pieces of text */ 64251876Speterstruct apr_text_header { 65251876Speter /** The first piece of text in the list */ 66251876Speter apr_text *first; 67251876Speter /** The last piece of text in the list */ 68251876Speter apr_text *last; 69251876Speter}; 70251876Speter 71251876Speter/** 72251876Speter * Append a piece of text to the end of a list 73251876Speter * @param p The pool to allocate out of 74251876Speter * @param hdr The text header to append to 75251876Speter * @param text The new text to append 76251876Speter */ 77251876SpeterAPU_DECLARE(void) apr_text_append(apr_pool_t *p, apr_text_header *hdr, 78251876Speter const char *text); 79251876Speter 80251876Speter 81251876Speter/* -------------------------------------------------------------------- 82251876Speter** 83251876Speter** XML PARSING 84251876Speter*/ 85251876Speter 86251876Speter/* 87251876Speter** Qualified namespace values 88251876Speter** 89251876Speter** APR_XML_NS_DAV_ID 90251876Speter** We always insert the "DAV:" namespace URI at the head of the 91251876Speter** namespace array. This means that it will always be at ID==0, 92251876Speter** making it much easier to test for. 93251876Speter** 94251876Speter** APR_XML_NS_NONE 95251876Speter** This special ID is used for two situations: 96251876Speter** 97251876Speter** 1) The namespace prefix begins with "xml" (and we do not know 98251876Speter** what it means). Namespace prefixes with "xml" (any case) as 99251876Speter** their first three characters are reserved by the XML Namespaces 100251876Speter** specification for future use. mod_dav will pass these through 101251876Speter** unchanged. When this identifier is used, the prefix is LEFT in 102251876Speter** the element/attribute name. Downstream processing should not 103251876Speter** prepend another prefix. 104251876Speter** 105251876Speter** 2) The element/attribute does not have a namespace. 106251876Speter** 107251876Speter** a) No prefix was used, and a default namespace has not been 108251876Speter** defined. 109251876Speter** b) No prefix was used, and the default namespace was specified 110251876Speter** to mean "no namespace". This is done with a namespace 111251876Speter** declaration of: xmlns="" 112251876Speter** (this declaration is typically used to override a previous 113251876Speter** specification for the default namespace) 114251876Speter** 115251876Speter** In these cases, we need to record that the elem/attr has no 116251876Speter** namespace so that we will not attempt to prepend a prefix. 117251876Speter** All namespaces that are used will have a prefix assigned to 118251876Speter** them -- mod_dav will never set or use the default namespace 119251876Speter** when generating XML. This means that "no prefix" will always 120251876Speter** mean "no namespace". 121251876Speter** 122251876Speter** In both cases, the XML generation will avoid prepending a prefix. 123251876Speter** For the first case, this means the original prefix/name will be 124251876Speter** inserted into the output stream. For the latter case, it means 125251876Speter** the name will have no prefix, and since we never define a default 126251876Speter** namespace, this means it will have no namespace. 127251876Speter** 128251876Speter** Note: currently, mod_dav understands the "xmlns" prefix and the 129251876Speter** "xml:lang" attribute. These are handled specially (they aren't 130251876Speter** left within the XML tree), so the APR_XML_NS_NONE value won't ever 131251876Speter** really apply to these values. 132251876Speter*/ 133251876Speter#define APR_XML_NS_DAV_ID 0 /**< namespace ID for "DAV:" */ 134251876Speter#define APR_XML_NS_NONE -10 /**< no namespace for this elem/attr */ 135251876Speter 136251876Speter#define APR_XML_NS_ERROR_BASE -100 /**< used only during processing */ 137251876Speter/** Is this namespace an error? */ 138251876Speter#define APR_XML_NS_IS_ERROR(e) ((e) <= APR_XML_NS_ERROR_BASE) 139251876Speter 140251876Speter/** @see apr_xml_attr */ 141251876Spetertypedef struct apr_xml_attr apr_xml_attr; 142251876Speter/** @see apr_xml_elem */ 143251876Spetertypedef struct apr_xml_elem apr_xml_elem; 144251876Speter/** @see apr_xml_doc */ 145251876Spetertypedef struct apr_xml_doc apr_xml_doc; 146251876Speter 147251876Speter/** apr_xml_attr: holds a parsed XML attribute */ 148251876Speterstruct apr_xml_attr { 149251876Speter /** attribute name */ 150251876Speter const char *name; 151251876Speter /** index into namespace array */ 152251876Speter int ns; 153251876Speter 154251876Speter /** attribute value */ 155251876Speter const char *value; 156251876Speter 157251876Speter /** next attribute */ 158251876Speter struct apr_xml_attr *next; 159251876Speter}; 160251876Speter 161251876Speter/** apr_xml_elem: holds a parsed XML element */ 162251876Speterstruct apr_xml_elem { 163251876Speter /** element name */ 164251876Speter const char *name; 165251876Speter /** index into namespace array */ 166251876Speter int ns; 167251876Speter /** xml:lang for attrs/contents */ 168251876Speter const char *lang; 169251876Speter 170251876Speter /** cdata right after start tag */ 171251876Speter apr_text_header first_cdata; 172251876Speter /** cdata after MY end tag */ 173251876Speter apr_text_header following_cdata; 174251876Speter 175251876Speter /** parent element */ 176251876Speter struct apr_xml_elem *parent; 177251876Speter /** next (sibling) element */ 178251876Speter struct apr_xml_elem *next; 179251876Speter /** first child element */ 180251876Speter struct apr_xml_elem *first_child; 181251876Speter /** first attribute */ 182251876Speter struct apr_xml_attr *attr; 183251876Speter 184251876Speter /* used only during parsing */ 185251876Speter /** last child element */ 186251876Speter struct apr_xml_elem *last_child; 187251876Speter /** namespaces scoped by this elem */ 188251876Speter struct apr_xml_ns_scope *ns_scope; 189251876Speter 190251876Speter /* used by modules during request processing */ 191251876Speter /** Place for modules to store private data */ 192251876Speter void *priv; 193251876Speter}; 194251876Speter 195251876Speter/** Is this XML element empty? */ 196251876Speter#define APR_XML_ELEM_IS_EMPTY(e) ((e)->first_child == NULL && \ 197251876Speter (e)->first_cdata.first == NULL) 198251876Speter 199251876Speter/** apr_xml_doc: holds a parsed XML document */ 200251876Speterstruct apr_xml_doc { 201251876Speter /** root element */ 202251876Speter apr_xml_elem *root; 203251876Speter /** array of namespaces used */ 204251876Speter apr_array_header_t *namespaces; 205251876Speter}; 206251876Speter 207251876Speter/** Opaque XML parser structure */ 208251876Spetertypedef struct apr_xml_parser apr_xml_parser; 209251876Speter 210251876Speter/** 211251876Speter * Create an XML parser 212251876Speter * @param pool The pool for allocating the parser and the parse results. 213251876Speter * @return The new parser. 214251876Speter */ 215251876SpeterAPU_DECLARE(apr_xml_parser *) apr_xml_parser_create(apr_pool_t *pool); 216251876Speter 217251876Speter/** 218251876Speter * Parse a File, producing a xml_doc 219251876Speter * @param p The pool for allocating the parse results. 220251876Speter * @param parser A pointer to *parser (needed so calling function can get 221251876Speter * errors), will be set to NULL on successful completion. 222251876Speter * @param ppdoc A pointer to *apr_xml_doc (which has the parsed results in it) 223251876Speter * @param xmlfd A file to read from. 224251876Speter * @param buffer_length Buffer length which would be suitable 225251876Speter * @return Any errors found during parsing. 226251876Speter */ 227251876SpeterAPU_DECLARE(apr_status_t) apr_xml_parse_file(apr_pool_t *p, 228251876Speter apr_xml_parser **parser, 229251876Speter apr_xml_doc **ppdoc, 230251876Speter apr_file_t *xmlfd, 231251876Speter apr_size_t buffer_length); 232251876Speter 233251876Speter 234251876Speter/** 235251876Speter * Feed input into the parser 236251876Speter * @param parser The XML parser for parsing this data. 237251876Speter * @param data The data to parse. 238251876Speter * @param len The length of the data. 239251876Speter * @return Any errors found during parsing. 240251876Speter * @remark Use apr_xml_parser_geterror() to get more error information. 241251876Speter */ 242251876SpeterAPU_DECLARE(apr_status_t) apr_xml_parser_feed(apr_xml_parser *parser, 243251876Speter const char *data, 244251876Speter apr_size_t len); 245251876Speter 246251876Speter/** 247251876Speter * Terminate the parsing and return the result 248251876Speter * @param parser The XML parser for parsing this data. 249251876Speter * @param pdoc The resulting parse information. May be NULL to simply 250251876Speter * terminate the parsing without fetching the info. 251251876Speter * @return Any errors found during the final stage of parsing. 252251876Speter * @remark Use apr_xml_parser_geterror() to get more error information. 253251876Speter */ 254251876SpeterAPU_DECLARE(apr_status_t) apr_xml_parser_done(apr_xml_parser *parser, 255251876Speter apr_xml_doc **pdoc); 256251876Speter 257251876Speter/** 258251876Speter * Fetch additional error information from the parser. 259251876Speter * @param parser The XML parser to query for errors. 260251876Speter * @param errbuf A buffer for storing error text. 261251876Speter * @param errbufsize The length of the error text buffer. 262251876Speter * @return The error buffer 263251876Speter */ 264251876SpeterAPU_DECLARE(char *) apr_xml_parser_geterror(apr_xml_parser *parser, 265251876Speter char *errbuf, 266251876Speter apr_size_t errbufsize); 267251876Speter 268251876Speter 269251876Speter/** 270251876Speter * Converts an XML element tree to flat text 271251876Speter * @param p The pool to allocate out of 272251876Speter * @param elem The XML element to convert 273251876Speter * @param style How to covert the XML. One of: 274251876Speter * <PRE> 275251876Speter * APR_XML_X2T_FULL start tag, contents, end tag 276251876Speter * APR_XML_X2T_INNER contents only 277251876Speter * APR_XML_X2T_LANG_INNER xml:lang + inner contents 278251876Speter * APR_XML_X2T_FULL_NS_LANG FULL + ns defns + xml:lang 279251876Speter * </PRE> 280251876Speter * @param namespaces The namespace of the current XML element 281251876Speter * @param ns_map Namespace mapping 282251876Speter * @param pbuf Buffer to put the converted text into 283251876Speter * @param psize Size of the converted text 284251876Speter */ 285251876SpeterAPU_DECLARE(void) apr_xml_to_text(apr_pool_t *p, const apr_xml_elem *elem, 286251876Speter int style, apr_array_header_t *namespaces, 287251876Speter int *ns_map, const char **pbuf, 288251876Speter apr_size_t *psize); 289251876Speter 290251876Speter/* style argument values: */ 291251876Speter#define APR_XML_X2T_FULL 0 /**< start tag, contents, end tag */ 292251876Speter#define APR_XML_X2T_INNER 1 /**< contents only */ 293251876Speter#define APR_XML_X2T_LANG_INNER 2 /**< xml:lang + inner contents */ 294251876Speter#define APR_XML_X2T_FULL_NS_LANG 3 /**< FULL + ns defns + xml:lang */ 295251876Speter 296251876Speter/** 297251876Speter * empty XML element 298251876Speter * @param p The pool to allocate out of 299251876Speter * @param elem The XML element to empty 300251876Speter * @return the string that was stored in the XML element 301251876Speter */ 302251876SpeterAPU_DECLARE(const char *) apr_xml_empty_elem(apr_pool_t *p, 303251876Speter const apr_xml_elem *elem); 304251876Speter 305251876Speter/** 306251876Speter * quote an XML string 307251876Speter * Replace '\<', '\>', and '\&' with '\<', '\>', and '\&'. 308251876Speter * @param p The pool to allocate out of 309251876Speter * @param s The string to quote 310251876Speter * @param quotes If quotes is true, then replace '"' with '\"'. 311251876Speter * @return The quoted string 312251876Speter * @note If the string does not contain special characters, it is not 313251876Speter * duplicated into the pool and the original string is returned. 314251876Speter */ 315251876SpeterAPU_DECLARE(const char *) apr_xml_quote_string(apr_pool_t *p, const char *s, 316251876Speter int quotes); 317251876Speter 318251876Speter/** 319251876Speter * Quote an XML element 320251876Speter * @param p The pool to allocate out of 321251876Speter * @param elem The element to quote 322251876Speter */ 323251876SpeterAPU_DECLARE(void) apr_xml_quote_elem(apr_pool_t *p, apr_xml_elem *elem); 324251876Speter 325251876Speter/* manage an array of unique URIs: apr_xml_insert_uri() and APR_XML_URI_ITEM() */ 326251876Speter 327251876Speter/** 328251876Speter * return the URI's (existing) index, or insert it and return a new index 329251876Speter * @param uri_array array to insert into 330251876Speter * @param uri The uri to insert 331251876Speter * @return int The uri's index 332251876Speter */ 333251876SpeterAPU_DECLARE(int) apr_xml_insert_uri(apr_array_header_t *uri_array, 334251876Speter const char *uri); 335251876Speter 336251876Speter/** Get the URI item for this XML element */ 337251876Speter#define APR_XML_GET_URI_ITEM(ary, i) (((const char * const *)(ary)->elts)[i]) 338251876Speter 339251876Speter#if APR_CHARSET_EBCDIC 340251876Speter/** 341251876Speter * Convert parsed tree in EBCDIC 342251876Speter * @param p The pool to allocate out of 343251876Speter * @param pdoc The apr_xml_doc to convert. 344251876Speter * @param xlate The translation handle to use. 345251876Speter * @return Any errors found during conversion. 346251876Speter */ 347251876SpeterAPU_DECLARE(apr_status_t) apr_xml_parser_convert_doc(apr_pool_t *p, 348251876Speter apr_xml_doc *pdoc, 349251876Speter apr_xlate_t *convset); 350251876Speter#endif 351251876Speter 352251876Speter#ifdef __cplusplus 353251876Speter} 354251876Speter#endif 355251876Speter/** @} */ 356251876Speter#endif /* APR_XML_H */ 357