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