1 /* 2 * xlink.c : implementation of the hyperlinks detection module 3 * This version supports both XML XLinks and HTML simple links 4 * 5 * See Copyright for the status of this software. 6 * 7 * daniel@veillard.com 8 */ 9 10 11 #define IN_LIBXML 12 #include "libxml.h" 13 14 #ifdef LIBXML_XPTR_ENABLED 15 #include <string.h> /* for memset() only */ 16 #include <ctype.h> 17 #include <stdlib.h> 18 19 #include <libxml/xmlmemory.h> 20 #include <libxml/tree.h> 21 #include <libxml/parser.h> 22 #include <libxml/valid.h> 23 #include <libxml/xlink.h> 24 #include <libxml/globals.h> 25 26 #define XLINK_NAMESPACE (BAD_CAST "http://www.w3.org/1999/xlink/namespace/") 27 #define XHTML_NAMESPACE (BAD_CAST "http://www.w3.org/1999/xhtml/") 28 29 /**************************************************************** 30 * * 31 * Default setting and related functions * 32 * * 33 ****************************************************************/ 34 35 static xlinkHandlerPtr xlinkDefaultHandler = NULL; 36 static xlinkNodeDetectFunc xlinkDefaultDetect = NULL; 37 38 /** 39 * xlinkGetDefaultHandler: 40 * 41 * Get the default xlink handler. 42 * 43 * Returns the current xlinkHandlerPtr value. 44 */ 45 xlinkHandlerPtr 46 xlinkGetDefaultHandler(void) { 47 return(xlinkDefaultHandler); 48 } 49 50 51 /** 52 * xlinkSetDefaultHandler: 53 * @handler: the new value for the xlink handler block 54 * 55 * Set the default xlink handlers 56 */ 57 void 58 xlinkSetDefaultHandler(xlinkHandlerPtr handler) { 59 xlinkDefaultHandler = handler; 60 } 61 62 /** 63 * xlinkGetDefaultDetect: 64 * 65 * Get the default xlink detection routine 66 * 67 * Returns the current function or NULL; 68 */ 69 xlinkNodeDetectFunc 70 xlinkGetDefaultDetect (void) { 71 return(xlinkDefaultDetect); 72 } 73 74 /** 75 * xlinkSetDefaultDetect: 76 * @func: pointer to the new detection routine. 77 * 78 * Set the default xlink detection routine 79 */ 80 void 81 xlinkSetDefaultDetect (xlinkNodeDetectFunc func) { 82 xlinkDefaultDetect = func; 83 } 84 85 /**************************************************************** 86 * * 87 * The detection routines * 88 * * 89 ****************************************************************/ 90 91 92 /** 93 * xlinkIsLink: 94 * @doc: the document containing the node 95 * @node: the node pointer itself 96 * 97 * Check whether the given node carries the attributes needed 98 * to be a link element (or is one of the linking elements issued 99 * from the (X)HTML DtDs). 100 * This routine don't try to do full checking of the link validity 101 * but tries to detect and return the appropriate link type. 102 * 103 * Returns the xlinkType of the node (XLINK_TYPE_NONE if there is no 104 * link detected. 105 */ 106 xlinkType 107 xlinkIsLink (xmlDocPtr doc, xmlNodePtr node) { 108 xmlChar *type = NULL, *role = NULL; 109 xlinkType ret = XLINK_TYPE_NONE; 110 111 if (node == NULL) return(XLINK_TYPE_NONE); 112 if (doc == NULL) doc = node->doc; 113 if ((doc != NULL) && (doc->type == XML_HTML_DOCUMENT_NODE)) { 114 /* 115 * This is an HTML document. 116 */ 117 } else if ((node->ns != NULL) && 118 (xmlStrEqual(node->ns->href, XHTML_NAMESPACE))) { 119 /* 120 * !!!! We really need an IS_XHTML_ELEMENT function from HTMLtree.h @@@ 121 */ 122 /* 123 * This is an XHTML element within an XML document 124 * Check whether it's one of the element able to carry links 125 * and in that case if it holds the attributes. 126 */ 127 } 128 129 /* 130 * We don't prevent a-priori having XML Linking constructs on 131 * XHTML elements 132 */ 133 type = xmlGetNsProp(node, BAD_CAST"type", XLINK_NAMESPACE); 134 if (type != NULL) { 135 if (xmlStrEqual(type, BAD_CAST "simple")) { 136 ret = XLINK_TYPE_SIMPLE; 137 } else if (xmlStrEqual(type, BAD_CAST "extended")) { 138 role = xmlGetNsProp(node, BAD_CAST "role", XLINK_NAMESPACE); 139 if (role != NULL) { 140 xmlNsPtr xlink; 141 xlink = xmlSearchNs(doc, node, XLINK_NAMESPACE); 142 if (xlink == NULL) { 143 /* Humm, fallback method */ 144 if (xmlStrEqual(role, BAD_CAST"xlink:external-linkset")) 145 ret = XLINK_TYPE_EXTENDED_SET; 146 } else { 147 xmlChar buf[200]; 148 snprintf((char *) buf, sizeof(buf), "%s:external-linkset", 149 (char *) xlink->prefix); 150 buf[sizeof(buf) - 1] = 0; 151 if (xmlStrEqual(role, buf)) 152 ret = XLINK_TYPE_EXTENDED_SET; 153 154 } 155 156 } 157 ret = XLINK_TYPE_EXTENDED; 158 } 159 } 160 161 if (type != NULL) xmlFree(type); 162 if (role != NULL) xmlFree(role); 163 return(ret); 164 } 165 #endif /* LIBXML_XPTR_ENABLED */ 166