xmlj_dom.c 70 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618
  1. /* xmlj_dom.c -
  2. Copyright (C) 2004 Free Software Foundation, Inc.
  3. This file is part of GNU Classpath.
  4. GNU Classpath is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2, or (at your option)
  7. any later version.
  8. GNU Classpath is distributed in the hope that it will be useful, but
  9. WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with GNU Classpath; see the file COPYING. If not, write to the
  14. Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  15. 02110-1301 USA.
  16. Linking this library statically or dynamically with other modules is
  17. making a combined work based on this library. Thus, the terms and
  18. conditions of the GNU General Public License cover the whole
  19. combination.
  20. As a special exception, the copyright holders of this library give you
  21. permission to link this library with independent modules to produce an
  22. executable, regardless of the license terms of these independent
  23. modules, and to copy and distribute the resulting executable under
  24. terms of your choice, provided that you also meet, for each linked
  25. independent module, the terms and conditions of the license of that
  26. module. An independent module is a module which is not derived from
  27. or based on this library. If you modify this library, you may extend
  28. this exception to your version of the library, but you are not
  29. obligated to do so. If you do not wish to do so, delete this
  30. exception statement from your version. */
  31. #include "xmlj_dom.h"
  32. #include "xmlj_error.h"
  33. #include "xmlj_io.h"
  34. #include "xmlj_node.h"
  35. #include "xmlj_sax.h"
  36. #include "xmlj_util.h"
  37. #include <sys/types.h>
  38. #include <sys/stat.h>
  39. #include <fcntl.h>
  40. #include <unistd.h>
  41. JNIEnv *dom_cb_env;
  42. jobject dom_cb_obj;
  43. typedef struct
  44. {
  45. int index;
  46. int count;
  47. xmlNodePtr node;
  48. }
  49. xmljHashScanData;
  50. /* Prototypes for local functions */
  51. void
  52. xmljAddAttribute (xmlNodePtr node, xmlAttrPtr attr);
  53. void
  54. xmljHashScanner (void *payload, void *vdata, xmlChar *name);
  55. xmlChar *
  56. xmljGetNodeValue (xmlNodePtr node);
  57. /*
  58. * Determines whether a child node is suitable for insertion in the list of
  59. * children for a given parent node.
  60. * Returns 0 on success, a DOMException code otherwise.
  61. */
  62. void
  63. xmljValidateChildNode (JNIEnv *env, xmlNodePtr parent, xmlNodePtr child)
  64. {
  65. xmlNodePtr cur;
  66. if (child == NULL || parent == NULL)
  67. {
  68. xmljThrowDOMException (env, 8, NULL); /* NOT_FOUND_ERR */
  69. return;
  70. }
  71. if (child->doc != parent->doc)
  72. {
  73. xmljThrowDOMException (env, 4, NULL); /* WRONG_DOCUMENT_ERR */
  74. return;
  75. }
  76. /* Check that new parent is of an allowed type */
  77. switch (parent->type)
  78. {
  79. case XML_CDATA_SECTION_NODE:
  80. case XML_COMMENT_NODE:
  81. case XML_TEXT_NODE:
  82. case XML_ENTITY_NODE:
  83. case XML_ENTITY_REF_NODE:
  84. case XML_NOTATION_NODE:
  85. case XML_PI_NODE:
  86. /* these can't have any children */
  87. /* HIERARCHY_REQUEST_ERR */
  88. xmljThrowDOMException (env, 3, "parent type does not allow children");
  89. return;
  90. case XML_ATTRIBUTE_NODE:
  91. if (child->type != XML_TEXT_NODE &&
  92. child->type != XML_ENTITY_REF_NODE)
  93. {
  94. /* HIERARCHY_REQUEST_ERR */
  95. xmljThrowDOMException (env, 3, "attributes may only contain text or entity reference nodes");
  96. return;
  97. }
  98. break;
  99. case XML_DOCUMENT_FRAG_NODE:
  100. case XML_ELEMENT_NODE:
  101. if (child->type == XML_DTD_NODE ||
  102. child->type == XML_DOCUMENT_TYPE_NODE ||
  103. child->type == XML_ENTITY_NODE ||
  104. child->type == XML_NOTATION_NODE ||
  105. child->type == XML_PI_NODE)
  106. {
  107. /* HIERARCHY_REQUEST_ERR */
  108. xmljThrowDOMException (env, 3, "parent type does not allow child of this type");
  109. return;
  110. }
  111. /* fall through */
  112. default:
  113. if (child->type == XML_ATTRIBUTE_NODE ||
  114. child->type == XML_DOCUMENT_NODE ||
  115. child->type == XML_DOCUMENT_FRAG_NODE)
  116. {
  117. /* HIERARCHY_REQUEST_ERR */
  118. xmljThrowDOMException (env, 3, "node type may not be a child");
  119. return;
  120. }
  121. /* TODO others? */
  122. }
  123. /* Check that new parent is not self or an ancestor */
  124. for (cur = parent; cur != NULL; cur = cur->parent)
  125. {
  126. if (cur == child)
  127. {
  128. /* HIERARCHY_REQUEST_ERR */
  129. xmljThrowDOMException (env, 3, "child cannot be an ancestor of itself");
  130. return;
  131. }
  132. }
  133. /* Check that new parent does not add a second doctype or root element
  134. * to a document parent */
  135. if (parent->type == XML_DOCUMENT_NODE)
  136. {
  137. cur = parent->children;
  138. while (cur != NULL)
  139. {
  140. if (cur->type == XML_DTD_NODE ||
  141. cur->type == XML_DOCUMENT_TYPE_NODE ||
  142. (cur->type == XML_ELEMENT_NODE &&
  143. parent->type == XML_DOCUMENT_NODE))
  144. {
  145. if (child->type == cur->type && child != cur)
  146. {
  147. /* HIERARCHY_REQUEST_ERR */
  148. xmljThrowDOMException (env, 3, "cannot add a second doctype or root element");
  149. return;
  150. }
  151. }
  152. cur = cur->next;
  153. }
  154. }
  155. }
  156. /*
  157. * Adds the specified attribute node to the list of attributes for the given
  158. * element.
  159. */
  160. void
  161. xmljAddAttribute (xmlNodePtr node, xmlAttrPtr attr)
  162. {
  163. xmlAttrPtr cur = node->properties;
  164. if (cur == NULL)
  165. {
  166. node->properties = attr;
  167. attr->prev = NULL;
  168. attr->next = NULL;
  169. attr->parent = node;
  170. attr->doc = node->doc;
  171. }
  172. else
  173. {
  174. while (cur->next != NULL)
  175. {
  176. cur = cur->next;
  177. }
  178. cur->next = attr;
  179. attr->prev = cur;
  180. attr->next = NULL;
  181. attr->parent = node;
  182. attr->doc = node->doc;
  183. }
  184. }
  185. /* -- GnomeAttr -- */
  186. JNIEXPORT jboolean JNICALL
  187. Java_gnu_xml_libxmlj_dom_GnomeAttr_getSpecified (JNIEnv * env, jobject self)
  188. {
  189. xmlAttrPtr attr;
  190. attr = (xmlAttrPtr) xmljGetNodeID (env, self);
  191. return (attr->atype != 0);
  192. }
  193. JNIEXPORT jstring JNICALL
  194. Java_gnu_xml_libxmlj_dom_GnomeAttr_getValue (JNIEnv * env, jobject self)
  195. {
  196. xmlNodePtr node;
  197. xmlChar *text;
  198. jstring ret;
  199. node = xmljGetNodeID (env, self);
  200. text = xmlNodeGetContent (node);
  201. ret = xmljNewString (env, (const xmlChar *) text);
  202. if (text != NULL)
  203. {
  204. xmlFree (text);
  205. }
  206. return ret;
  207. }
  208. JNIEXPORT void JNICALL
  209. Java_gnu_xml_libxmlj_dom_GnomeAttr_setValue (JNIEnv * env,
  210. jobject self, jstring value)
  211. {
  212. xmlNodePtr node;
  213. const xmlChar *s_value;
  214. node = xmljGetNodeID (env, self);
  215. s_value = xmljGetStringChars (env, value);
  216. xmlNodeSetContent (node, s_value);
  217. }
  218. JNIEXPORT jboolean JNICALL
  219. Java_gnu_xml_libxmlj_dom_GnomeAttr_xmljIsId (JNIEnv * env, jobject self)
  220. {
  221. xmlAttrPtr attr;
  222. attr = (xmlAttrPtr) xmljGetNodeID (env, self);
  223. return (attr->atype == XML_ATTRIBUTE_ID);
  224. }
  225. /* -- GnomeDocument -- */
  226. JNIEXPORT void JNICALL
  227. Java_gnu_xml_libxmlj_dom_GnomeDocument_free (JNIEnv * env,
  228. jobject self
  229. __attribute__ ((__unused__)),
  230. jobject id)
  231. {
  232. xmlDocPtr doc;
  233. doc = (xmlDocPtr) xmljAsPointer (env, id);
  234. xmljFreeDoc (env, doc);
  235. xmlFree (doc);
  236. }
  237. JNIEXPORT jobject JNICALL
  238. Java_gnu_xml_libxmlj_dom_GnomeDocument_getDoctype (JNIEnv * env, jobject self)
  239. {
  240. xmlDocPtr doc;
  241. xmlDtdPtr dtd;
  242. doc = (xmlDocPtr) xmljGetNodeID (env, self);
  243. dtd = doc->extSubset;
  244. if (dtd == NULL)
  245. {
  246. dtd = doc->intSubset;
  247. }
  248. return xmljGetNodeInstance (env, (xmlNodePtr) dtd);
  249. }
  250. JNIEXPORT jobject JNICALL
  251. Java_gnu_xml_libxmlj_dom_GnomeDocument_getDocumentElement (JNIEnv * env,
  252. jobject self)
  253. {
  254. xmlDocPtr doc;
  255. doc = (xmlDocPtr) xmljGetNodeID (env, self);
  256. return xmljGetNodeInstance (env, xmlDocGetRootElement (doc));
  257. }
  258. JNIEXPORT jobject JNICALL
  259. Java_gnu_xml_libxmlj_dom_GnomeDocument_createDocumentType (JNIEnv * env,
  260. jobject self,
  261. jstring name,
  262. jstring publicId,
  263. jstring systemId)
  264. {
  265. xmlDocPtr doc;
  266. xmlDtdPtr dtd;
  267. doc = (xmlDocPtr) xmljGetNodeID (env, self);
  268. dtd = xmlNewDtd (doc,
  269. xmljGetStringChars (env, name),
  270. xmljGetStringChars (env, publicId),
  271. xmljGetStringChars (env, systemId));
  272. return xmljGetNodeInstance (env, (xmlNodePtr) dtd);
  273. }
  274. JNIEXPORT jobject JNICALL
  275. Java_gnu_xml_libxmlj_dom_GnomeDocument_createDocumentFragment (JNIEnv * env,
  276. jobject self)
  277. {
  278. xmlDocPtr doc;
  279. doc = (xmlDocPtr) xmljGetNodeID (env, self);
  280. return xmljGetNodeInstance (env, xmlNewDocFragment (doc));
  281. }
  282. JNIEXPORT jobject JNICALL
  283. Java_gnu_xml_libxmlj_dom_GnomeDocument_createTextNode (JNIEnv * env,
  284. jobject self,
  285. jstring data)
  286. {
  287. xmlDocPtr doc;
  288. xmlNodePtr text;
  289. const xmlChar *s_data;
  290. doc = (xmlDocPtr) xmljGetNodeID (env, self);
  291. s_data = xmljGetStringChars (env, data);
  292. text = xmlNewDocText (doc, s_data);
  293. return xmljGetNodeInstance (env, text);
  294. }
  295. JNIEXPORT jobject JNICALL
  296. Java_gnu_xml_libxmlj_dom_GnomeDocument_createComment (JNIEnv * env,
  297. jobject self,
  298. jstring data)
  299. {
  300. xmlDocPtr doc;
  301. xmlNodePtr comment;
  302. const xmlChar *s_data;
  303. doc = (xmlDocPtr) xmljGetNodeID (env, self);
  304. s_data = xmljGetStringChars (env, data);
  305. comment = xmlNewDocComment (doc, s_data);
  306. return xmljGetNodeInstance (env, comment);
  307. }
  308. JNIEXPORT jobject JNICALL
  309. Java_gnu_xml_libxmlj_dom_GnomeDocument_createCDATASection (JNIEnv * env,
  310. jobject self,
  311. jstring data)
  312. {
  313. xmlDocPtr doc;
  314. xmlNodePtr cdata;
  315. const xmlChar *s_data;
  316. int len;
  317. doc = (xmlDocPtr) xmljGetNodeID (env, self);
  318. s_data = xmljGetStringChars (env, data);
  319. len = xmlStrlen (s_data);
  320. cdata = xmlNewCDataBlock (doc, s_data, len);
  321. return xmljGetNodeInstance (env, cdata);
  322. }
  323. JNIEXPORT jobject JNICALL
  324. Java_gnu_xml_libxmlj_dom_GnomeDocument_createProcessingInstruction (JNIEnv *
  325. env,
  326. jobject
  327. self,
  328. jstring
  329. target,
  330. jstring
  331. data)
  332. {
  333. xmlDocPtr doc;
  334. xmlNodePtr pi;
  335. const xmlChar *s_target;
  336. const xmlChar *s_data;
  337. doc = (xmlDocPtr) xmljGetNodeID (env, self);
  338. s_target = xmljGetStringChars (env, target);
  339. s_data = xmljGetStringChars (env, data);
  340. pi = xmlNewPI (s_target, s_data);
  341. pi->doc = doc;
  342. return xmljGetNodeInstance (env, pi);
  343. }
  344. JNIEXPORT jobject JNICALL
  345. Java_gnu_xml_libxmlj_dom_GnomeDocument_createEntityReference (JNIEnv * env,
  346. jobject self,
  347. jstring name)
  348. {
  349. xmlDocPtr doc;
  350. xmlNodePtr ref;
  351. const xmlChar *s_name;
  352. doc = (xmlDocPtr) xmljGetNodeID (env, self);
  353. s_name = xmljGetStringChars (env, name);
  354. ref = xmlNewReference (doc, s_name);
  355. return xmljGetNodeInstance (env, ref);
  356. }
  357. JNIEXPORT jobject JNICALL
  358. Java_gnu_xml_libxmlj_dom_GnomeDocument_xmljImportNode (JNIEnv * env,
  359. jobject self,
  360. jobject importedNode,
  361. jboolean deep)
  362. {
  363. xmlDocPtr doc;
  364. xmlNodePtr node;
  365. doc = (xmlDocPtr) xmljGetNodeID (env, self);
  366. node = xmljGetNodeID (env, importedNode);
  367. if (node == NULL)
  368. {
  369. xmljThrowDOMException (env, 8, NULL); /* NOT_FOUND_ERR */
  370. return NULL;
  371. }
  372. if (node->type == XML_DOCUMENT_NODE ||
  373. node->type == XML_DOCUMENT_TYPE_NODE)
  374. {
  375. xmljThrowDOMException (env, 9, NULL); /* NOT_SUPPORTED_ERR */
  376. return NULL;
  377. }
  378. node = xmlDocCopyNode (node, doc, deep);
  379. return xmljGetNodeInstance (env, node);
  380. }
  381. JNIEXPORT jobject JNICALL
  382. Java_gnu_xml_libxmlj_dom_GnomeDocument_createElementNS (JNIEnv * env,
  383. jobject self,
  384. jstring uri,
  385. jstring qName)
  386. {
  387. xmlDocPtr doc;
  388. xmlNodePtr element;
  389. xmlNsPtr ns = NULL;
  390. const xmlChar *s_uri;
  391. const xmlChar *s_qName;
  392. const xmlChar *s_prefix;
  393. const xmlChar *s_localName;
  394. doc = (xmlDocPtr) xmljGetNodeID (env, self);
  395. s_qName = xmljGetStringChars (env, qName);
  396. if (xmlValidateQName (s_qName, 0))
  397. {
  398. xmljThrowDOMException (env, 5, NULL); /* INVALID_CHARACTER_ERR */
  399. return NULL;
  400. }
  401. if (uri != NULL)
  402. {
  403. s_uri = xmljGetStringChars (env, uri);
  404. s_prefix = xmljGetPrefix (s_qName);
  405. s_localName = xmljGetLocalName (s_qName);
  406. ns = xmlNewNs ((xmlNodePtr) doc, s_uri, s_prefix);
  407. }
  408. element = xmlNewDocNode (doc, ns, s_qName, NULL);
  409. return xmljGetNodeInstance (env, element);
  410. }
  411. JNIEXPORT jobject JNICALL
  412. Java_gnu_xml_libxmlj_dom_GnomeDocument_createAttributeNS (JNIEnv * env,
  413. jobject self,
  414. jstring uri,
  415. jstring qName)
  416. {
  417. xmlDocPtr doc;
  418. xmlNodePtr attr;
  419. xmlNsPtr ns = NULL;
  420. const xmlChar *s_uri;
  421. const xmlChar *s_qName;
  422. const xmlChar *s_prefix;
  423. const xmlChar *s_localName;
  424. doc = (xmlDocPtr) xmljGetNodeID (env, self);
  425. s_qName = xmljGetStringChars (env, qName);
  426. if (xmlValidateQName (s_qName, 0))
  427. {
  428. xmljThrowDOMException (env, 5, NULL); /* INVALID_CHARACTER_ERR */
  429. return NULL;
  430. }
  431. if (uri != NULL)
  432. {
  433. s_uri = xmljGetStringChars (env, uri);
  434. s_prefix = xmljGetPrefix (s_qName);
  435. s_localName = xmljGetLocalName (s_qName);
  436. ns = xmlNewNs ((xmlNodePtr) doc, s_uri, s_prefix);
  437. }
  438. attr = (xmlNodePtr) xmlNewNsProp ((xmlNodePtr) doc, ns, s_qName, NULL);
  439. attr->parent = NULL;
  440. return xmljGetNodeInstance (env, attr);
  441. }
  442. JNIEXPORT jobject JNICALL
  443. Java_gnu_xml_libxmlj_dom_GnomeDocument_xmljGetElementById (JNIEnv * env,
  444. jobject self,
  445. jstring elementId)
  446. {
  447. xmlDocPtr doc;
  448. xmlNodePtr ctx, tmp;
  449. xmlAttrPtr attr;
  450. const xmlChar *id;
  451. const xmlChar *val;
  452. doc = (xmlDocPtr) xmljGetNodeID (env, self);
  453. id = xmljGetStringChars (env, elementId);
  454. ctx = xmlDocGetRootElement (doc);
  455. while (ctx && ctx != (xmlNodePtr) doc)
  456. {
  457. if (ctx->type == XML_ELEMENT_NODE)
  458. {
  459. for (attr = ctx->properties; attr;
  460. attr = (xmlAttrPtr) attr->next)
  461. {
  462. if (xmlIsID (doc, ctx, attr))
  463. {
  464. val = xmlGetProp (ctx, attr->name);
  465. if (val && xmlStrEqual (id, val))
  466. {
  467. return xmljGetNodeInstance (env, ctx);
  468. }
  469. }
  470. }
  471. }
  472. if (ctx->children)
  473. {
  474. ctx = ctx->children;
  475. }
  476. else
  477. {
  478. tmp = ctx->next;
  479. if (tmp)
  480. {
  481. ctx = tmp;
  482. }
  483. else
  484. {
  485. do
  486. {
  487. tmp = ctx->parent;
  488. if (!tmp)
  489. {
  490. return NULL;
  491. }
  492. ctx = tmp;
  493. tmp = ctx->next;
  494. }
  495. while (!tmp);
  496. ctx = tmp;
  497. }
  498. }
  499. }
  500. return NULL;
  501. }
  502. JNIEXPORT jstring JNICALL
  503. Java_gnu_xml_libxmlj_dom_GnomeDocument_getInputEncoding (JNIEnv * env,
  504. jobject self)
  505. {
  506. xmlDocPtr doc;
  507. doc = (xmlDocPtr) xmljGetNodeID (env, self);
  508. if (doc->encoding)
  509. {
  510. return xmljNewString (env, doc->encoding);
  511. }
  512. switch (doc->charset)
  513. {
  514. case XML_CHAR_ENCODING_ASCII:
  515. return xmljNewString (env, BAD_CAST "US-ASCII");
  516. case XML_CHAR_ENCODING_UTF16LE:
  517. return xmljNewString (env, BAD_CAST "UTF-16LE");
  518. case XML_CHAR_ENCODING_UTF16BE:
  519. return xmljNewString (env, BAD_CAST "UTF-16BE");
  520. case XML_CHAR_ENCODING_8859_1:
  521. return xmljNewString (env, BAD_CAST "ISO-8859-1");
  522. /* TODO others */
  523. default:
  524. return xmljNewString (env, BAD_CAST "UTF-8");
  525. }
  526. }
  527. JNIEXPORT jstring JNICALL
  528. Java_gnu_xml_libxmlj_dom_GnomeDocument_getXmlEncoding (JNIEnv * env,
  529. jobject self)
  530. {
  531. xmlDocPtr doc;
  532. doc = (xmlDocPtr) xmljGetNodeID (env, self);
  533. return (doc->encoding == NULL) ?
  534. xmljNewString (env, BAD_CAST "UTF-8") :
  535. xmljNewString (env, doc->encoding);
  536. }
  537. JNIEXPORT jboolean JNICALL
  538. Java_gnu_xml_libxmlj_dom_GnomeDocument_getXmlStandalone (JNIEnv * env,
  539. jobject self)
  540. {
  541. xmlDocPtr doc;
  542. doc = (xmlDocPtr) xmljGetNodeID (env, self);
  543. return doc->standalone;
  544. }
  545. JNIEXPORT void JNICALL
  546. Java_gnu_xml_libxmlj_dom_GnomeDocument_setXmlStandalone (JNIEnv * env,
  547. jobject self,
  548. jboolean xmlStandalone)
  549. {
  550. xmlDocPtr doc;
  551. doc = (xmlDocPtr) xmljGetNodeID (env, self);
  552. doc->standalone = xmlStandalone;
  553. }
  554. JNIEXPORT jstring JNICALL
  555. Java_gnu_xml_libxmlj_dom_GnomeDocument_getXmlVersion (JNIEnv * env,
  556. jobject self)
  557. {
  558. xmlDocPtr doc;
  559. doc = (xmlDocPtr) xmljGetNodeID (env, self);
  560. return (doc->version == NULL) ?
  561. xmljNewString (env, BAD_CAST "1.0") :
  562. xmljNewString (env, doc->version);
  563. }
  564. JNIEXPORT void JNICALL
  565. Java_gnu_xml_libxmlj_dom_GnomeDocument_setXmlVersion (JNIEnv * env,
  566. jobject self,
  567. jstring xmlVersion)
  568. {
  569. xmlDocPtr doc;
  570. doc = (xmlDocPtr) xmljGetNodeID (env, self);
  571. if (xmlVersion == NULL)
  572. {
  573. doc->version = NULL;
  574. }
  575. else
  576. {
  577. const xmlChar *version = xmljGetStringChars (env, xmlVersion);
  578. if (!xmlStrEqual (version, BAD_CAST "1.0") &&
  579. !xmlStrEqual (version, BAD_CAST "1.1"))
  580. {
  581. xmljThrowDOMException (env, 9, NULL); /* NOT_SUPPORTED_ERR */
  582. return;
  583. }
  584. doc->version = version;
  585. }
  586. }
  587. JNIEXPORT jstring JNICALL
  588. Java_gnu_xml_libxmlj_dom_GnomeDocument_getDocumentURI (JNIEnv * env,
  589. jobject self)
  590. {
  591. xmlDocPtr doc;
  592. doc = (xmlDocPtr) xmljGetNodeID (env, self);
  593. return (doc->name == NULL) ? NULL :
  594. xmljNewString (env, (const xmlChar *) doc->URL);
  595. }
  596. JNIEXPORT void JNICALL
  597. Java_gnu_xml_libxmlj_dom_GnomeDocument_setDocumentURI (JNIEnv * env,
  598. jobject self,
  599. jstring documentURI)
  600. {
  601. xmlDocPtr doc;
  602. doc = (xmlDocPtr) xmljGetNodeID (env, self);
  603. if (documentURI == NULL)
  604. {
  605. doc->URL = NULL;
  606. }
  607. else
  608. {
  609. doc->URL = xmljGetStringChars (env, documentURI);
  610. }
  611. }
  612. JNIEXPORT jobject JNICALL
  613. Java_gnu_xml_libxmlj_dom_GnomeDocument_xmljAdoptNode (JNIEnv *env,
  614. jobject self,
  615. jobject jnode)
  616. {
  617. xmlDocPtr doc;
  618. xmlNodePtr node;
  619. doc = (xmlDocPtr) xmljGetNodeID (env, self);
  620. node = xmljGetNodeID (env, jnode);
  621. if (node == NULL)
  622. {
  623. xmljThrowDOMException (env, 8, NULL); /* NOT_FOUND_ERR */
  624. return NULL;
  625. }
  626. if (node->type == XML_DOCUMENT_NODE ||
  627. node->type == XML_DOCUMENT_TYPE_NODE ||
  628. node->type == XML_ENTITY_NODE ||
  629. node->type == XML_NOTATION_NODE)
  630. {
  631. xmljThrowDOMException (env, 9, NULL); /* NOT_SUPPORTED_ERR */
  632. return NULL;
  633. }
  634. xmlUnlinkNode (node);
  635. node = xmlDocCopyNode (node, doc, 1);
  636. return xmljGetNodeInstance (env, node);
  637. }
  638. JNIEXPORT jobject JNICALL
  639. Java_gnu_xml_libxmlj_dom_GnomeDocument_renameNode (JNIEnv * env,
  640. jobject self
  641. __attribute__ ((__unused__)),
  642. jobject n
  643. __attribute__ ((__unused__)),
  644. jstring namespaceURI
  645. __attribute__ ((__unused__)),
  646. jstring qName
  647. __attribute__ ((__unused__)))
  648. {
  649. xmlNodePtr node;
  650. xmlNsPtr ns;
  651. const xmlChar *s_qName;
  652. const xmlChar *href;
  653. const xmlChar *prefix;
  654. int *len;
  655. node = xmljGetNodeID (env, n);
  656. if (node == NULL)
  657. {
  658. xmljThrowDOMException (env, 8, NULL); /* NOT_FOUND_ERR */
  659. return NULL;
  660. }
  661. s_qName = xmljGetStringChars (env, qName);
  662. if (xmlValidateQName (s_qName, 0))
  663. {
  664. xmljThrowDOMException (env, 5, NULL); /* INVALID_CHARACTER_ERR */
  665. return NULL;
  666. }
  667. xmlNodeSetName (node, s_qName);
  668. href = xmljGetStringChars (env, namespaceURI);
  669. len = (int *) malloc (sizeof (int));
  670. prefix = xmlSplitQName3 (s_qName, len);
  671. ns = node->ns;
  672. if (ns == NULL)
  673. {
  674. if (href != NULL)
  675. {
  676. ns = xmlNewNs (node, href, prefix);
  677. xmlSetNs (node, ns);
  678. }
  679. }
  680. else
  681. {
  682. node->ns = NULL;
  683. /*xmlFreeNs (ns); FIXME this can segfault (?) */
  684. if (href != NULL)
  685. {
  686. ns = xmlNewNs (node, href, prefix);
  687. xmlSetNs (node, ns);
  688. }
  689. }
  690. free (len);
  691. return n;
  692. }
  693. /* -- GnomeDocumentBuilder -- */
  694. JNIEXPORT jobject JNICALL
  695. Java_gnu_xml_libxmlj_dom_GnomeDocumentBuilder_parseStream (JNIEnv * env,
  696. jobject self,
  697. jobject in,
  698. jbyteArray
  699. detectBuffer,
  700. jstring publicId,
  701. jstring systemId,
  702. jstring base,
  703. jboolean validate,
  704. jboolean coalesce,
  705. jboolean
  706. expandEntities,
  707. jboolean
  708. entityResolver,
  709. jboolean
  710. errorHandler)
  711. {
  712. xmlDocPtr doc;
  713. doc = xmljParseDocument(env,
  714. self,
  715. in,
  716. detectBuffer,
  717. publicId,
  718. systemId,
  719. base,
  720. validate,
  721. coalesce,
  722. expandEntities,
  723. 0,
  724. 0,
  725. entityResolver,
  726. errorHandler,
  727. 0,
  728. 0,
  729. 1);
  730. return xmljCreateDocument (env, self, doc);
  731. }
  732. JNIEXPORT jobject JNICALL
  733. Java_gnu_xml_libxmlj_dom_GnomeDocumentBuilder_createDocument
  734. (JNIEnv * env,
  735. jobject self,
  736. jstring namespaceURI,
  737. jstring qualifiedName,
  738. jobject doctype)
  739. {
  740. xmlDocPtr doc;
  741. xmlNodePtr root;
  742. xmlNsPtr ns;
  743. const xmlChar *href;
  744. const xmlChar *prefix;
  745. const xmlChar *qName;
  746. qName = xmljGetStringChars (env, qualifiedName);
  747. href = xmljGetStringChars (env, namespaceURI);
  748. if (qName == NULL)
  749. {
  750. prefix = NULL;
  751. }
  752. else
  753. {
  754. int *len;
  755. len = (int *) malloc (sizeof (int));
  756. prefix = xmlSplitQName3 (qName, len);
  757. free (len);
  758. }
  759. /* Create the document node */
  760. doc = xmlNewDoc (BAD_CAST "1.0");
  761. /* doctype */
  762. if (doctype != NULL)
  763. {
  764. jclass cls;
  765. jmethodID method;
  766. jstring ret;
  767. const xmlChar *name;
  768. const xmlChar *publicId;
  769. const xmlChar *systemId;
  770. const xmlChar *internalSubset;
  771. xmlDtdPtr dtd;
  772. cls = (*env)->FindClass (env, "org/w3c/dom/DocumentType");
  773. if (cls == NULL)
  774. {
  775. return NULL;
  776. }
  777. /* name */
  778. method = (*env)->GetMethodID (env, cls, "getName",
  779. "()Ljava/lang/String;");
  780. if (method == NULL)
  781. {
  782. return NULL;
  783. }
  784. ret = (jstring) (*env)->CallObjectMethod (env, doctype, method);
  785. name = xmljGetStringChars (env, ret);
  786. /* publicId */
  787. method = (*env)->GetMethodID (env, cls, "getPublicId",
  788. "()Ljava/lang/String;");
  789. if (method == NULL)
  790. {
  791. return NULL;
  792. }
  793. ret = (jstring) (*env)->CallObjectMethod (env, doctype, method);
  794. publicId = xmljGetStringChars (env, ret);
  795. /* systemId */
  796. method = (*env)->GetMethodID (env, cls, "getSystemId",
  797. "()Ljava/lang/String;");
  798. if (method == NULL)
  799. {
  800. return NULL;
  801. }
  802. ret = (jstring) (*env)->CallObjectMethod (env, doctype, method);
  803. systemId = xmljGetStringChars (env, ret);
  804. /* internalSubset */
  805. method = (*env)->GetMethodID (env, cls, "getInternalSubset",
  806. "()Ljava/lang/String;");
  807. if (method == NULL)
  808. {
  809. return NULL;
  810. }
  811. ret = (jstring) (*env)->CallObjectMethod (env, doctype, method);
  812. internalSubset = xmljGetStringChars (env, ret);
  813. /* TODO notations */
  814. /* TODO entities */
  815. if (internalSubset == NULL)
  816. {
  817. dtd = xmlNewDtd (doc, name, publicId, systemId);
  818. }
  819. else
  820. {
  821. dtd = xmlCreateIntSubset (doc, name, publicId, systemId);
  822. /* TODO parse internal subset? */
  823. xmljThrowDOMException (env, 9, NULL); /* NOT_SUPPORTED_ERR */
  824. return NULL;
  825. }
  826. }
  827. /* Create the root element */
  828. root = xmlNewNode (NULL, qName);
  829. xmlDocSetRootElement (doc, root);
  830. ns = xmlNewNs (root, href, prefix);
  831. xmlSetNs (root, ns);
  832. return xmljCreateDocument (env, self, doc);
  833. }
  834. /* -- GnomeDocumentType -- */
  835. JNIEXPORT jstring JNICALL
  836. Java_gnu_xml_libxmlj_dom_GnomeDocumentType_getPublicId (JNIEnv * env,
  837. jobject self)
  838. {
  839. xmlDtdPtr dtd;
  840. dtd = (xmlDtdPtr) xmljGetNodeID (env, self);
  841. return xmljNewString (env, dtd->ExternalID);
  842. }
  843. JNIEXPORT jstring JNICALL
  844. Java_gnu_xml_libxmlj_dom_GnomeDocumentType_getSystemId (JNIEnv * env,
  845. jobject self)
  846. {
  847. xmlDtdPtr dtd;
  848. dtd = (xmlDtdPtr) xmljGetNodeID (env, self);
  849. return xmljNewString (env, dtd->SystemID);
  850. }
  851. JNIEXPORT jstring JNICALL
  852. Java_gnu_xml_libxmlj_dom_GnomeDocumentType_getInternalSubset (JNIEnv * env,
  853. jobject self
  854. __attribute__ ((__unused__)))
  855. {
  856. /* TODO */
  857. xmljThrowDOMException (env, 9, NULL); /* NOT_SUPPORTED_ERR */
  858. return NULL;
  859. }
  860. /* -- GnomeElement -- */
  861. JNIEXPORT jstring JNICALL
  862. Java_gnu_xml_libxmlj_dom_GnomeElement_getAttribute (JNIEnv * env,
  863. jobject self,
  864. jstring name)
  865. {
  866. xmlNodePtr node;
  867. const xmlChar *s_name;
  868. const xmlChar *s_value;
  869. node = xmljGetNodeID (env, self);
  870. s_name = xmljGetStringChars (env, name);
  871. s_value = xmlGetProp (node, s_name);
  872. xmlFree ((xmlChar *) s_name);
  873. return (s_value == NULL) ?
  874. xmljNewString (env, BAD_CAST "") :
  875. xmljNewString (env, s_value);
  876. }
  877. JNIEXPORT void JNICALL
  878. Java_gnu_xml_libxmlj_dom_GnomeElement_setAttribute (JNIEnv * env,
  879. jobject self,
  880. jstring name,
  881. jstring value)
  882. {
  883. xmlNodePtr node;
  884. const xmlChar *s_name;
  885. const xmlChar *s_value;
  886. node = xmljGetNodeID (env, self);
  887. s_name = xmljGetStringChars (env, name);
  888. if (xmlValidateName (s_name, 0))
  889. {
  890. xmljThrowDOMException (env, 5, NULL); /* INVALID_CHARACTER_ERR */
  891. return;
  892. }
  893. s_value = xmljGetStringChars (env, value);
  894. xmlSetProp (node, s_name, s_value);
  895. }
  896. JNIEXPORT jobject JNICALL
  897. Java_gnu_xml_libxmlj_dom_GnomeElement_getAttributeNode (JNIEnv * env,
  898. jobject self,
  899. jstring name)
  900. {
  901. xmlNodePtr node;
  902. const xmlChar *s_name;
  903. xmlAttrPtr attr;
  904. node = xmljGetNodeID (env, self);
  905. s_name = xmljGetStringChars (env, name);
  906. attr = xmlHasProp (node, s_name);
  907. if (attr == NULL)
  908. {
  909. return NULL;
  910. }
  911. xmlFree ((xmlChar *) s_name);
  912. return xmljGetNodeInstance (env, (xmlNodePtr) attr);
  913. }
  914. JNIEXPORT jobject JNICALL
  915. Java_gnu_xml_libxmlj_dom_GnomeElement_setAttributeNode (JNIEnv * env,
  916. jobject self,
  917. jobject newAttr)
  918. {
  919. xmlNodePtr node;
  920. xmlAttrPtr new_attr;
  921. xmlAttrPtr old_attr;
  922. node = xmljGetNodeID (env, self);
  923. new_attr = (xmlAttrPtr) xmljGetNodeID (env, newAttr);
  924. if (new_attr->parent != NULL)
  925. {
  926. xmljThrowDOMException (env, 10, NULL); /* INUSE_ATTRIBUTE_ERR */
  927. return NULL;
  928. }
  929. if (new_attr->doc != node->doc)
  930. {
  931. xmljThrowDOMException (env, 4, NULL); /* WRONG_DOCUMENT_ERR */
  932. return NULL;
  933. }
  934. old_attr = xmlHasProp (node, new_attr->name);
  935. if (old_attr)
  936. {
  937. xmlUnlinkNode ((xmlNodePtr) old_attr);
  938. }
  939. xmljAddAttribute (node, new_attr);
  940. return xmljGetNodeInstance (env, (xmlNodePtr) old_attr);
  941. }
  942. JNIEXPORT jobject JNICALL
  943. Java_gnu_xml_libxmlj_dom_GnomeElement_removeAttributeNode (JNIEnv * env,
  944. jobject self
  945. __attribute__ ((__unused__)),
  946. jobject oldAttr)
  947. {
  948. xmlNodePtr attr;
  949. attr = xmljGetNodeID (env, oldAttr);
  950. xmlUnlinkNode (attr);
  951. return oldAttr;
  952. }
  953. JNIEXPORT jstring JNICALL
  954. Java_gnu_xml_libxmlj_dom_GnomeElement_getAttributeNS (JNIEnv * env,
  955. jobject self,
  956. jstring uri,
  957. jstring localName)
  958. {
  959. xmlNodePtr node;
  960. const xmlChar *s_uri;
  961. const xmlChar *s_localName;
  962. const xmlChar *s_value;
  963. node = xmljGetNodeID (env, self);
  964. s_localName = xmljGetStringChars (env, localName);
  965. if (uri == NULL)
  966. {
  967. s_value = xmlGetNoNsProp (node, s_localName);
  968. }
  969. else
  970. {
  971. s_uri = xmljGetStringChars (env, uri);
  972. s_value = xmlGetNsProp (node, s_localName, s_uri);
  973. xmlFree ((xmlChar *) s_uri);
  974. }
  975. xmlFree ((xmlChar *) s_localName);
  976. return (s_value == NULL) ?
  977. xmljNewString (env, BAD_CAST "") :
  978. xmljNewString (env, s_value);
  979. }
  980. JNIEXPORT void JNICALL
  981. Java_gnu_xml_libxmlj_dom_GnomeElement_setAttributeNS (JNIEnv * env,
  982. jobject self,
  983. jstring uri,
  984. jstring qName,
  985. jstring value)
  986. {
  987. xmlNodePtr node;
  988. xmlNsPtr ns;
  989. const xmlChar *s_uri;
  990. const xmlChar *s_qName;
  991. const xmlChar *s_prefix;
  992. const xmlChar *s_localName;
  993. const xmlChar *s_value;
  994. node = xmljGetNodeID (env, self);
  995. s_qName = xmljGetStringChars (env, qName);
  996. if (xmlValidateQName (s_qName, 0))
  997. {
  998. xmljThrowDOMException (env, 5, NULL); /* INVALID_CHARACTER_ERR */
  999. return;
  1000. }
  1001. s_value = xmljGetStringChars (env, value);
  1002. if (uri == NULL)
  1003. {
  1004. xmlSetProp (node, s_qName, s_value);
  1005. }
  1006. else
  1007. {
  1008. s_prefix = xmljGetPrefix (s_qName);
  1009. s_localName = xmljGetLocalName (s_qName);
  1010. s_uri = xmljGetStringChars (env, uri);
  1011. ns = xmlNewNs (node, s_uri, s_prefix);
  1012. xmlSetNsProp (node, ns, s_localName, s_value);
  1013. }
  1014. }
  1015. JNIEXPORT jobject JNICALL
  1016. Java_gnu_xml_libxmlj_dom_GnomeElement_getAttributeNodeNS (JNIEnv * env,
  1017. jobject self,
  1018. jstring uri,
  1019. jstring localName)
  1020. {
  1021. xmlNodePtr node;
  1022. xmlAttrPtr attr;
  1023. const xmlChar *s_uri;
  1024. const xmlChar *s_localName;
  1025. node = xmljGetNodeID (env, self);
  1026. attr = node->properties;
  1027. s_uri = xmljGetStringChars (env, uri);
  1028. s_localName = xmljGetStringChars (env, localName);
  1029. while (attr != NULL)
  1030. {
  1031. if (uri == NULL)
  1032. {
  1033. if (xmljMatch (s_localName, (xmlNodePtr) attr))
  1034. break;
  1035. }
  1036. else
  1037. {
  1038. if (xmljMatchNS (s_uri, s_localName, (xmlNodePtr) attr))
  1039. break;
  1040. }
  1041. attr = attr->next;
  1042. }
  1043. xmlFree ((xmlChar *) s_uri);
  1044. xmlFree ((xmlChar *) s_localName);
  1045. return xmljGetNodeInstance (env, (xmlNodePtr) attr);
  1046. }
  1047. JNIEXPORT jobject JNICALL
  1048. Java_gnu_xml_libxmlj_dom_GnomeElement_setAttributeNodeNS (JNIEnv * env,
  1049. jobject self,
  1050. jobject newAttr)
  1051. {
  1052. xmlNodePtr node;
  1053. xmlAttrPtr new_attr;
  1054. xmlAttrPtr old_attr;
  1055. const xmlChar *uri;
  1056. node = xmljGetNodeID (env, self);
  1057. new_attr = (xmlAttrPtr) xmljGetNodeID (env, newAttr);
  1058. if (new_attr->parent != NULL)
  1059. {
  1060. xmljThrowDOMException (env, 10, NULL); /* INUSE_ATTRIBUTE_ERR */
  1061. return NULL;
  1062. }
  1063. if (new_attr->doc != node->doc)
  1064. {
  1065. xmljThrowDOMException (env, 4, NULL); /* WRONG_DOCUMENT_ERR */
  1066. return NULL;
  1067. }
  1068. uri = (new_attr->ns != NULL) ? new_attr->ns->href : NULL;
  1069. old_attr = xmlHasNsProp (node, new_attr->name, uri);
  1070. if (old_attr)
  1071. {
  1072. xmlUnlinkNode ((xmlNodePtr) old_attr);
  1073. }
  1074. xmljAddAttribute (node, new_attr);
  1075. return xmljGetNodeInstance (env, (xmlNodePtr) old_attr);
  1076. }
  1077. JNIEXPORT jboolean JNICALL
  1078. Java_gnu_xml_libxmlj_dom_GnomeElement_hasAttribute (JNIEnv * env,
  1079. jobject self,
  1080. jstring name)
  1081. {
  1082. xmlNodePtr node;
  1083. const xmlChar *s_name;
  1084. const xmlChar *s_value;
  1085. node = xmljGetNodeID (env, self);
  1086. s_name = xmljGetStringChars (env, name);
  1087. s_value = xmlGetProp (node, s_name);
  1088. xmlFree ((xmlChar *) s_name);
  1089. return (s_value != NULL);
  1090. }
  1091. JNIEXPORT jboolean JNICALL
  1092. Java_gnu_xml_libxmlj_dom_GnomeElement_hasAttributeNS (JNIEnv * env,
  1093. jobject self,
  1094. jstring uri,
  1095. jstring localName)
  1096. {
  1097. xmlNodePtr node;
  1098. const xmlChar *s_uri;
  1099. const xmlChar *s_localName;
  1100. const xmlChar *s_value;
  1101. node = xmljGetNodeID (env, self);
  1102. s_localName = xmljGetStringChars (env, localName);
  1103. if (uri == NULL)
  1104. {
  1105. s_value = xmlGetNoNsProp (node, s_localName);
  1106. }
  1107. else
  1108. {
  1109. s_uri = xmljGetStringChars (env, uri);
  1110. s_value = xmlGetNsProp (node, s_localName, s_uri);
  1111. xmlFree ((xmlChar *) s_uri);
  1112. }
  1113. xmlFree ((xmlChar *) s_localName);
  1114. return (s_value != NULL);
  1115. }
  1116. /* -- GnomeEntity -- */
  1117. JNIEXPORT jstring JNICALL
  1118. Java_gnu_xml_libxmlj_dom_GnomeEntity_getPublicId (JNIEnv * env, jobject self)
  1119. {
  1120. xmlEntityPtr entity;
  1121. entity = (xmlEntityPtr) xmljGetNodeID (env, self);
  1122. return xmljNewString (env, entity->ExternalID);
  1123. }
  1124. JNIEXPORT jstring JNICALL
  1125. Java_gnu_xml_libxmlj_dom_GnomeEntity_getSystemId (JNIEnv * env, jobject self)
  1126. {
  1127. xmlEntityPtr entity;
  1128. entity = (xmlEntityPtr) xmljGetNodeID (env, self);
  1129. return xmljNewString (env, entity->SystemID);
  1130. }
  1131. JNIEXPORT jstring JNICALL
  1132. Java_gnu_xml_libxmlj_dom_GnomeEntity_getNotationName (JNIEnv * env,
  1133. jobject self
  1134. __attribute__ ((__unused__)))
  1135. {
  1136. /* TODO */
  1137. xmljThrowDOMException (env, 9, NULL); /* NOT_SUPPORTED_ERR */
  1138. return NULL;
  1139. }
  1140. /* -- GnomeNamedNodeMap -- */
  1141. JNIEXPORT jobject JNICALL
  1142. Java_gnu_xml_libxmlj_dom_GnomeNamedNodeMap_getNamedItem (JNIEnv * env,
  1143. jobject self,
  1144. jstring name)
  1145. {
  1146. jclass cls;
  1147. jfieldID field;
  1148. jint type;
  1149. cls = (*env)->GetObjectClass (env, self);
  1150. field = (*env)->GetFieldID (env, cls, "type", "I");
  1151. type = (*env)->GetIntField (env, self, field);
  1152. if (type == 0)
  1153. {
  1154. xmlAttrPtr attr;
  1155. attr = xmljGetNamedItem (env, self, name);
  1156. return xmljGetNodeInstance (env, (xmlNodePtr) attr);
  1157. }
  1158. else
  1159. {
  1160. xmlDtdPtr dtd;
  1161. xmlHashTablePtr hash;
  1162. const xmlChar *s_name;
  1163. xmlNodePtr ret;
  1164. dtd = (xmlDtdPtr) xmljGetNodeID (env, self);
  1165. hash = (xmlHashTablePtr) ((type == 1) ? dtd->entities : dtd->notations);
  1166. if (hash == NULL)
  1167. {
  1168. return NULL;
  1169. }
  1170. s_name = xmljGetStringChars (env, name);
  1171. ret = (xmlNodePtr) xmlHashLookup (hash, s_name);
  1172. xmlFree ((xmlChar *) s_name);
  1173. return xmljGetNodeInstance (env, ret);
  1174. }
  1175. }
  1176. JNIEXPORT jobject JNICALL
  1177. Java_gnu_xml_libxmlj_dom_GnomeNamedNodeMap_setNamedItem (JNIEnv * env,
  1178. jobject self,
  1179. jobject arg)
  1180. {
  1181. jclass cls;
  1182. jfieldID field;
  1183. jint type;
  1184. xmlNodePtr node;
  1185. xmlNodePtr argNode;
  1186. cls = (*env)->GetObjectClass (env, self);
  1187. field = (*env)->GetFieldID (env, cls, "type", "I");
  1188. type = (*env)->GetIntField (env, self, field);
  1189. node = xmljGetNodeID (env, self);
  1190. argNode = xmljGetNodeID (env, arg);
  1191. if (argNode->doc != node->doc)
  1192. {
  1193. xmljThrowDOMException (env, 4, NULL); /* WRONG_DOCUMENT_ERR */
  1194. }
  1195. xmljValidateChildNode (env, node, argNode);
  1196. if ((*env)->ExceptionOccurred (env))
  1197. {
  1198. return NULL;
  1199. }
  1200. if (type == 0)
  1201. {
  1202. if (argNode->parent != NULL)
  1203. {
  1204. xmljThrowDOMException (env, 10, NULL); /* INUSE_ATTRIBUTE_ERR */
  1205. return NULL;
  1206. }
  1207. xmlAddChild (node, argNode);
  1208. }
  1209. else
  1210. {
  1211. xmlDtdPtr dtd;
  1212. xmlHashTablePtr hash;
  1213. dtd = (xmlDtdPtr) xmljGetNodeID (env, self);
  1214. hash = (xmlHashTablePtr) ((type == 1) ? dtd->entities : dtd->notations);
  1215. if (hash == NULL)
  1216. {
  1217. hash = xmlHashCreate (10);
  1218. if (type == 1)
  1219. {
  1220. dtd->entities = hash;
  1221. }
  1222. else
  1223. {
  1224. dtd->notations = hash;
  1225. }
  1226. }
  1227. xmlHashAddEntry (hash, argNode->name, argNode);
  1228. }
  1229. return arg;
  1230. }
  1231. JNIEXPORT jobject JNICALL
  1232. Java_gnu_xml_libxmlj_dom_GnomeNamedNodeMap_removeNamedItem (JNIEnv * env,
  1233. jobject self,
  1234. jstring name)
  1235. {
  1236. jclass cls;
  1237. jfieldID field;
  1238. jint type;
  1239. cls = (*env)->GetObjectClass (env, self);
  1240. field = (*env)->GetFieldID (env, cls, "type", "I");
  1241. type = (*env)->GetIntField (env, self, field);
  1242. if (type == 0)
  1243. {
  1244. xmlAttrPtr attr;
  1245. attr = xmljGetNamedItem (env, self, name);
  1246. if (attr == NULL)
  1247. {
  1248. xmljThrowDOMException (env, 8, NULL); /* NOT_FOUND_ERR */
  1249. return NULL;
  1250. }
  1251. xmlUnlinkNode ((xmlNodePtr) attr);
  1252. return xmljGetNodeInstance (env, (xmlNodePtr) attr);
  1253. }
  1254. else
  1255. {
  1256. xmlDtdPtr dtd;
  1257. xmlHashTablePtr hash;
  1258. const xmlChar *s_name;
  1259. xmlNodePtr ret;
  1260. dtd = (xmlDtdPtr) xmljGetNodeID (env, self);
  1261. hash = (xmlHashTablePtr) ((type == 1) ? dtd->entities : dtd->notations);
  1262. if (hash == NULL)
  1263. {
  1264. return NULL;
  1265. }
  1266. s_name = xmljGetStringChars (env, name);
  1267. ret = (xmlNodePtr) xmlHashLookup (hash, s_name);
  1268. if (ret != NULL)
  1269. {
  1270. xmlHashRemoveEntry (hash, s_name, NULL);
  1271. }
  1272. xmlFree ((xmlChar *) s_name);
  1273. return xmljGetNodeInstance (env, ret);
  1274. }
  1275. }
  1276. void
  1277. xmljHashScanner (void *payload, void *vdata, xmlChar *name)
  1278. {
  1279. xmljHashScanData *data;
  1280. data = (xmljHashScanData *) vdata;
  1281. if (data->count <= data->index)
  1282. {
  1283. data->node = (xmlNodePtr) payload;
  1284. }
  1285. data->count++;
  1286. }
  1287. JNIEXPORT jobject JNICALL
  1288. Java_gnu_xml_libxmlj_dom_GnomeNamedNodeMap_item (JNIEnv * env,
  1289. jobject self, jint index)
  1290. {
  1291. jclass cls;
  1292. jfieldID field;
  1293. jint type;
  1294. cls = (*env)->GetObjectClass (env, self);
  1295. field = (*env)->GetFieldID (env, cls, "type", "I");
  1296. type = (*env)->GetIntField (env, self, field);
  1297. if (type == 0)
  1298. {
  1299. xmlNodePtr node;
  1300. xmlAttrPtr attr;
  1301. jint count;
  1302. node = xmljGetNodeID (env, self);
  1303. switch (node->type)
  1304. {
  1305. case XML_ELEMENT_NODE:
  1306. attr = node->properties;
  1307. for (count = 0; attr != NULL && count < index; count++)
  1308. {
  1309. attr = attr->next;
  1310. }
  1311. if (attr == NULL)
  1312. {
  1313. char msg[1024];
  1314. sprintf (msg, "No attribute at index %d\n", (int) index);
  1315. xmljThrowException (env, "java/lang/NullPointerException", msg);
  1316. return NULL;
  1317. }
  1318. return xmljGetNodeInstance (env, (xmlNodePtr) attr);
  1319. default:
  1320. return NULL;
  1321. }
  1322. }
  1323. else
  1324. {
  1325. xmlDtdPtr dtd;
  1326. xmlHashTablePtr hash;
  1327. xmljHashScanData *data;
  1328. xmlNodePtr ret;
  1329. dtd = (xmlDtdPtr) xmljGetNodeID (env, self);
  1330. hash = (xmlHashTablePtr) ((type == 1) ? dtd->entities : dtd->notations);
  1331. if (hash == NULL)
  1332. {
  1333. return NULL;
  1334. }
  1335. data = (xmljHashScanData *) malloc (sizeof (xmljHashScanData));
  1336. if (data == NULL)
  1337. {
  1338. return NULL;
  1339. }
  1340. data->index = index;
  1341. data->count = 0;
  1342. data->node = NULL;
  1343. xmlHashScan (hash, xmljHashScanner, data);
  1344. ret = data->node;
  1345. free (data);
  1346. return xmljGetNodeInstance (env, ret);
  1347. }
  1348. }
  1349. JNIEXPORT jint JNICALL
  1350. Java_gnu_xml_libxmlj_dom_GnomeNamedNodeMap_getLength (JNIEnv * env,
  1351. jobject self)
  1352. {
  1353. jclass cls;
  1354. jfieldID field;
  1355. jint type;
  1356. cls = (*env)->GetObjectClass (env, self);
  1357. field = (*env)->GetFieldID (env, cls, "type", "I");
  1358. type = (*env)->GetIntField (env, self, field);
  1359. if (type == 0)
  1360. {
  1361. xmlNodePtr node;
  1362. xmlAttrPtr attr;
  1363. jint count;
  1364. node = xmljGetNodeID (env, self);
  1365. switch (node->type)
  1366. {
  1367. case XML_ELEMENT_NODE:
  1368. count = 0;
  1369. attr = node->properties;
  1370. while (attr != NULL)
  1371. {
  1372. count++;
  1373. attr = attr->next;
  1374. }
  1375. return count;
  1376. default:
  1377. return -1;
  1378. }
  1379. }
  1380. else
  1381. {
  1382. xmlDtdPtr dtd;
  1383. xmlHashTablePtr hash;
  1384. xmljHashScanData *data;
  1385. jint ret;
  1386. dtd = (xmlDtdPtr) xmljGetNodeID (env, self);
  1387. hash = (xmlHashTablePtr) ((type == 1) ? dtd->entities : dtd->notations);
  1388. if (hash == NULL)
  1389. {
  1390. return 0;
  1391. }
  1392. data = (xmljHashScanData *) malloc (sizeof (xmljHashScanData));
  1393. if (data == NULL)
  1394. {
  1395. return 0;
  1396. }
  1397. data->index = -1;
  1398. data->count = 0;
  1399. data->node = NULL;
  1400. xmlHashScan (hash, xmljHashScanner, data);
  1401. ret = data->count;
  1402. free (data);
  1403. return ret;
  1404. }
  1405. }
  1406. JNIEXPORT jobject JNICALL
  1407. Java_gnu_xml_libxmlj_dom_GnomeNamedNodeMap_getNamedItemNS (JNIEnv * env,
  1408. jobject self,
  1409. jstring uri,
  1410. jstring localName)
  1411. {
  1412. jclass cls;
  1413. jfieldID field;
  1414. jint type;
  1415. cls = (*env)->GetObjectClass (env, self);
  1416. field = (*env)->GetFieldID (env, cls, "type", "I");
  1417. type = (*env)->GetIntField (env, self, field);
  1418. if (type == 0)
  1419. {
  1420. xmlAttrPtr attr;
  1421. attr = xmljGetNamedItemNS (env, self, uri, localName);
  1422. return xmljGetNodeInstance (env, (xmlNodePtr) attr);
  1423. }
  1424. else
  1425. {
  1426. return NULL;
  1427. }
  1428. }
  1429. JNIEXPORT jobject JNICALL
  1430. Java_gnu_xml_libxmlj_dom_GnomeNamedNodeMap_setNamedItemNS (JNIEnv * env,
  1431. jobject self,
  1432. jobject arg)
  1433. {
  1434. return Java_gnu_xml_libxmlj_dom_GnomeNamedNodeMap_setNamedItem (env, self,
  1435. arg);
  1436. }
  1437. JNIEXPORT jobject JNICALL
  1438. Java_gnu_xml_libxmlj_dom_GnomeNamedNodeMap_removeNamedItemNS (JNIEnv * env,
  1439. jobject self,
  1440. jstring uri,
  1441. jstring
  1442. localName)
  1443. {
  1444. jclass cls;
  1445. jfieldID field;
  1446. jint type;
  1447. cls = (*env)->GetObjectClass (env, self);
  1448. field = (*env)->GetFieldID (env, cls, "type", "I");
  1449. type = (*env)->GetIntField (env, self, field);
  1450. if (type == 0)
  1451. {
  1452. xmlAttrPtr attr;
  1453. attr = xmljGetNamedItemNS (env, self, uri, localName);
  1454. if (attr == NULL)
  1455. {
  1456. xmljThrowDOMException (env, 8, NULL); /* NOT_FOUND_ERR */
  1457. return NULL;
  1458. }
  1459. else
  1460. {
  1461. xmlUnlinkNode ((xmlNodePtr) attr);
  1462. return xmljGetNodeInstance (env, (xmlNodePtr) attr);
  1463. }
  1464. }
  1465. else
  1466. {
  1467. return NULL;
  1468. }
  1469. }
  1470. /* -- GnomeNode -- */
  1471. JNIEXPORT jstring JNICALL
  1472. Java_gnu_xml_libxmlj_dom_GnomeNode_getNodeName (JNIEnv * env, jobject self)
  1473. {
  1474. xmlNodePtr node;
  1475. node = xmljGetNodeID (env, self);
  1476. if (node == NULL)
  1477. {
  1478. return NULL;
  1479. }
  1480. return xmljNewString (env, node->name);
  1481. }
  1482. xmlChar *
  1483. xmljGetNodeValue (xmlNodePtr node)
  1484. {
  1485. /* If not character data, return null */
  1486. switch (node->type)
  1487. {
  1488. case XML_TEXT_NODE:
  1489. case XML_CDATA_SECTION_NODE:
  1490. case XML_COMMENT_NODE:
  1491. case XML_ATTRIBUTE_NODE:
  1492. return xmlNodeGetContent (node);
  1493. default:
  1494. return NULL;
  1495. }
  1496. }
  1497. JNIEXPORT jstring JNICALL
  1498. Java_gnu_xml_libxmlj_dom_GnomeNode_getNodeValue (JNIEnv * env, jobject self)
  1499. {
  1500. xmlNodePtr node;
  1501. xmlChar *text;
  1502. jstring ret;
  1503. node = xmljGetNodeID (env, self);
  1504. text = xmljGetNodeValue (node);
  1505. ret = xmljNewString (env, (const xmlChar *) text);
  1506. if (text != NULL)
  1507. {
  1508. xmlFree (text);
  1509. }
  1510. return ret;
  1511. }
  1512. JNIEXPORT void JNICALL
  1513. Java_gnu_xml_libxmlj_dom_GnomeNode_setNodeValue (JNIEnv * env,
  1514. jobject self,
  1515. jstring nodeValue)
  1516. {
  1517. xmlNodePtr node;
  1518. const xmlChar *s_nodeValue;
  1519. node = xmljGetNodeID (env, self);
  1520. /* If not character data, return */
  1521. if (node->type != XML_TEXT_NODE &&
  1522. node->type != XML_CDATA_SECTION_NODE && node->type != XML_COMMENT_NODE)
  1523. return;
  1524. s_nodeValue = xmljGetStringChars (env, nodeValue);
  1525. xmlNodeSetContent (node, s_nodeValue);
  1526. }
  1527. JNIEXPORT jshort JNICALL
  1528. Java_gnu_xml_libxmlj_dom_GnomeNode_getNodeType (JNIEnv * env, jobject self)
  1529. {
  1530. xmlNodePtr node;
  1531. node = xmljGetNodeID (env, self);
  1532. switch (node->type)
  1533. {
  1534. case XML_DTD_NODE:
  1535. return XML_DOCUMENT_TYPE_NODE;
  1536. case XML_ATTRIBUTE_DECL:
  1537. return XML_ATTRIBUTE_NODE;
  1538. case XML_ENTITY_DECL:
  1539. return XML_ENTITY_NODE;
  1540. default:
  1541. return node->type;
  1542. }
  1543. }
  1544. JNIEXPORT jobject JNICALL
  1545. Java_gnu_xml_libxmlj_dom_GnomeNode_getParentNode (JNIEnv * env, jobject self)
  1546. {
  1547. xmlNodePtr node;
  1548. node = xmljGetNodeID (env, self);
  1549. return xmljGetNodeInstance (env, node->parent);
  1550. }
  1551. JNIEXPORT jobject JNICALL
  1552. Java_gnu_xml_libxmlj_dom_GnomeNode_getFirstChild (JNIEnv * env, jobject self)
  1553. {
  1554. xmlNodePtr node;
  1555. node = xmljGetNodeID (env, self);
  1556. return xmljGetNodeInstance (env, node->children);
  1557. }
  1558. JNIEXPORT jobject JNICALL
  1559. Java_gnu_xml_libxmlj_dom_GnomeNode_getLastChild (JNIEnv * env, jobject self)
  1560. {
  1561. xmlNodePtr node;
  1562. node = xmljGetNodeID (env, self);
  1563. return xmljGetNodeInstance (env, node->last);
  1564. }
  1565. JNIEXPORT jobject JNICALL
  1566. Java_gnu_xml_libxmlj_dom_GnomeNode_getPreviousSibling (JNIEnv * env,
  1567. jobject self)
  1568. {
  1569. xmlNodePtr node;
  1570. node = xmljGetNodeID (env, self);
  1571. return xmljGetNodeInstance (env, node->prev);
  1572. }
  1573. JNIEXPORT jobject JNICALL
  1574. Java_gnu_xml_libxmlj_dom_GnomeNode_getNextSibling (JNIEnv * env, jobject self)
  1575. {
  1576. xmlNodePtr node;
  1577. node = xmljGetNodeID (env, self);
  1578. return xmljGetNodeInstance (env, node->next);
  1579. }
  1580. JNIEXPORT jobject JNICALL
  1581. Java_gnu_xml_libxmlj_dom_GnomeNode_getOwnerDocument (JNIEnv * env,
  1582. jobject self)
  1583. {
  1584. xmlNodePtr node;
  1585. node = xmljGetNodeID (env, self);
  1586. return xmljGetNodeInstance (env, (xmlNodePtr) node->doc);
  1587. }
  1588. JNIEXPORT jobject JNICALL
  1589. Java_gnu_xml_libxmlj_dom_GnomeNode_xmljInsertBefore (JNIEnv * env,
  1590. jobject self,
  1591. jobject newChild,
  1592. jobject refChild)
  1593. {
  1594. xmlNodePtr node;
  1595. xmlNodePtr newChildNode;
  1596. xmlNodePtr refChildNode;
  1597. node = xmljGetNodeID (env, self);
  1598. newChildNode = xmljGetNodeID (env, newChild);
  1599. refChildNode = xmljGetNodeID (env, refChild);
  1600. /* Is refChildNode a child of this node? */
  1601. if (refChildNode == NULL ||
  1602. refChildNode->parent == NULL ||
  1603. refChildNode->parent != node)
  1604. {
  1605. xmljThrowDOMException (env, 8, NULL); /* NOT_FOUND_ERR */
  1606. return NULL;
  1607. }
  1608. /* Check new child */
  1609. xmljValidateChildNode (env, node, newChildNode);
  1610. if ((*env)->ExceptionOccurred (env))
  1611. {
  1612. return NULL;
  1613. }
  1614. newChildNode = xmlAddPrevSibling (refChildNode, newChildNode);
  1615. return xmljGetNodeInstance (env, newChildNode);
  1616. }
  1617. JNIEXPORT jobject JNICALL
  1618. Java_gnu_xml_libxmlj_dom_GnomeNode_xmljReplaceChild (JNIEnv * env,
  1619. jobject self,
  1620. jobject newChild,
  1621. jobject oldChild)
  1622. {
  1623. xmlNodePtr node;
  1624. xmlNodePtr newChildNode;
  1625. xmlNodePtr oldChildNode;
  1626. node = xmljGetNodeID (env, self);
  1627. newChildNode = xmljGetNodeID (env, newChild);
  1628. oldChildNode = xmljGetNodeID (env, oldChild);
  1629. /* Is oldChildNode a child of this node? */
  1630. if (oldChildNode == NULL ||
  1631. oldChildNode->parent == NULL ||
  1632. oldChildNode->parent != node)
  1633. {
  1634. xmljThrowDOMException (env, 8, NULL); /* NOT_FOUND_ERR */
  1635. return NULL;
  1636. }
  1637. /* Check new child */
  1638. xmljValidateChildNode (env, node, newChildNode);
  1639. if ((*env)->ExceptionOccurred (env))
  1640. {
  1641. return NULL;
  1642. }
  1643. newChildNode = xmlReplaceNode (oldChildNode, newChildNode);
  1644. return xmljGetNodeInstance (env, newChildNode);
  1645. }
  1646. JNIEXPORT jobject JNICALL
  1647. Java_gnu_xml_libxmlj_dom_GnomeNode_xmljRemoveChild (JNIEnv * env,
  1648. jobject self,
  1649. jobject oldChild)
  1650. {
  1651. xmlNodePtr node;
  1652. xmlNodePtr oldChildNode;
  1653. node = xmljGetNodeID (env, self);
  1654. oldChildNode = xmljGetNodeID (env, oldChild);
  1655. if (oldChildNode == NULL ||
  1656. oldChildNode->parent == NULL ||
  1657. oldChildNode->parent != node)
  1658. {
  1659. xmljThrowDOMException (env, 8, NULL); /* NOT_FOUND_ERR */
  1660. return NULL;
  1661. }
  1662. xmlUnlinkNode (oldChildNode);
  1663. return oldChild;
  1664. }
  1665. JNIEXPORT jobject JNICALL
  1666. Java_gnu_xml_libxmlj_dom_GnomeNode_xmljAppendChild (JNIEnv * env,
  1667. jobject self,
  1668. jobject newChild)
  1669. {
  1670. xmlNodePtr node;
  1671. xmlNodePtr newChildNode;
  1672. node = xmljGetNodeID (env, self);
  1673. newChildNode = xmljGetNodeID (env, newChild);
  1674. /* Check new child */
  1675. xmljValidateChildNode (env, node, newChildNode);
  1676. if ((*env)->ExceptionOccurred (env))
  1677. {
  1678. return NULL;
  1679. }
  1680. newChildNode = xmlAddChild (node, newChildNode);
  1681. return xmljGetNodeInstance (env, newChildNode);
  1682. }
  1683. JNIEXPORT jboolean JNICALL
  1684. Java_gnu_xml_libxmlj_dom_GnomeNode_hasChildNodes (JNIEnv * env, jobject self)
  1685. {
  1686. xmlNodePtr node;
  1687. node = xmljGetNodeID (env, self);
  1688. return (node->children != NULL);
  1689. }
  1690. JNIEXPORT jobject JNICALL
  1691. Java_gnu_xml_libxmlj_dom_GnomeNode_xmljCloneNode (JNIEnv * env,
  1692. jobject self, jboolean deep)
  1693. {
  1694. xmlNodePtr node;
  1695. xmlNodePtr clone;
  1696. node = xmljGetNodeID (env, self);
  1697. clone = xmlCopyNode (node, deep);
  1698. clone->parent = NULL;
  1699. clone->doc = node->doc;
  1700. return xmljGetNodeInstance (env, clone);
  1701. }
  1702. JNIEXPORT void JNICALL
  1703. Java_gnu_xml_libxmlj_dom_GnomeNode_normalize (JNIEnv * env, jobject self)
  1704. {
  1705. xmlNodePtr node;
  1706. node = xmljGetNodeID (env, self);
  1707. xmljNormalizeNode (node);
  1708. }
  1709. void
  1710. xmljNormalizeNode (xmlNodePtr node)
  1711. {
  1712. xmlNodePtr cur;
  1713. xmlNodePtr last = NULL;
  1714. cur = node->children;
  1715. while (cur != NULL)
  1716. {
  1717. switch (cur->type)
  1718. {
  1719. case XML_CDATA_SECTION_NODE:
  1720. case XML_TEXT_NODE:
  1721. if (xmlIsBlankNode (cur))
  1722. {
  1723. xmlNodePtr next = cur->next;
  1724. xmlUnlinkNode (cur);
  1725. xmlFreeNode (cur);
  1726. cur = next;
  1727. continue;
  1728. }
  1729. if (last != NULL)
  1730. {
  1731. last = xmlTextMerge (last, cur);
  1732. xmlUnlinkNode (cur);
  1733. xmlFreeNode (cur);
  1734. cur = last;
  1735. }
  1736. else
  1737. {
  1738. last = cur;
  1739. }
  1740. break;
  1741. default:
  1742. last = NULL;
  1743. xmljNormalizeNode (cur);
  1744. }
  1745. cur = cur->next;
  1746. }
  1747. }
  1748. JNIEXPORT jstring JNICALL
  1749. Java_gnu_xml_libxmlj_dom_GnomeNode_getNamespaceURI (JNIEnv * env,
  1750. jobject self)
  1751. {
  1752. xmlNodePtr node;
  1753. node = xmljGetNodeID (env, self);
  1754. if (node->type != XML_ELEMENT_NODE &&
  1755. node->type != XML_ATTRIBUTE_NODE)
  1756. {
  1757. return NULL;
  1758. }
  1759. if (node->ns == NULL)
  1760. {
  1761. return NULL;
  1762. }
  1763. return xmljNewString (env, node->ns->href);
  1764. }
  1765. JNIEXPORT jstring JNICALL
  1766. Java_gnu_xml_libxmlj_dom_GnomeNode_getPrefix (JNIEnv * env, jobject self)
  1767. {
  1768. xmlNodePtr node;
  1769. node = xmljGetNodeID (env, self);
  1770. if (node->type != XML_ELEMENT_NODE &&
  1771. node->type != XML_ATTRIBUTE_NODE)
  1772. {
  1773. return NULL;
  1774. }
  1775. if (node->ns == NULL)
  1776. {
  1777. return NULL;
  1778. }
  1779. return xmljNewString (env, node->ns->prefix);
  1780. }
  1781. JNIEXPORT void JNICALL
  1782. Java_gnu_xml_libxmlj_dom_GnomeNode_setPrefix (JNIEnv * env,
  1783. jobject self, jstring prefix)
  1784. {
  1785. xmlNodePtr node;
  1786. const xmlChar *s_prefix;
  1787. s_prefix = xmljGetStringChars (env, prefix);
  1788. if (xmlValidateName (s_prefix, 0))
  1789. {
  1790. xmljThrowDOMException (env, 5, NULL); /* INVALID_CHARACTER_ERR */
  1791. }
  1792. node = xmljGetNodeID (env, self);
  1793. if (node->type != XML_ELEMENT_NODE &&
  1794. node->type != XML_ATTRIBUTE_NODE)
  1795. {
  1796. xmljThrowDOMException (env, 3, NULL); /* HIERARCHY_REQUEST_ERR */
  1797. return;
  1798. }
  1799. if (node->ns == NULL)
  1800. {
  1801. xmljThrowDOMException (env, 14, NULL); /* NAMESPACE_ERR */
  1802. return;
  1803. }
  1804. node->ns->prefix = s_prefix;
  1805. }
  1806. JNIEXPORT jstring JNICALL
  1807. Java_gnu_xml_libxmlj_dom_GnomeNode_getLocalName (JNIEnv * env, jobject self)
  1808. {
  1809. xmlNodePtr node;
  1810. int *len;
  1811. jstring ret;
  1812. node = xmljGetNodeID (env, self);
  1813. if (node->name == NULL)
  1814. {
  1815. return NULL;
  1816. }
  1817. len = (int *) malloc (sizeof (int));
  1818. if (xmlSplitQName3 (node->name, len) != NULL)
  1819. {
  1820. ret = xmljNewString (env, node->name + (*len));
  1821. }
  1822. else
  1823. {
  1824. ret = xmljNewString (env, node->name);
  1825. }
  1826. free (len);
  1827. return ret;
  1828. }
  1829. JNIEXPORT jboolean JNICALL
  1830. Java_gnu_xml_libxmlj_dom_GnomeNode_hasAttributes (JNIEnv * env, jobject self)
  1831. {
  1832. xmlNodePtr node;
  1833. node = xmljGetNodeID (env, self);
  1834. return (node->properties != NULL);
  1835. }
  1836. JNIEXPORT jstring JNICALL
  1837. Java_gnu_xml_libxmlj_dom_GnomeNode_getBaseURI (JNIEnv * env, jobject self)
  1838. {
  1839. xmlNodePtr node;
  1840. xmlChar *baseURI;
  1841. jstring ret;
  1842. node = xmljGetNodeID (env, self);
  1843. baseURI = xmlNodeGetBase (node->doc, node);
  1844. ret = xmljNewString (env, (const xmlChar *) baseURI);
  1845. if (baseURI != NULL)
  1846. {
  1847. xmlFree (baseURI);
  1848. }
  1849. return ret;
  1850. }
  1851. JNIEXPORT jstring JNICALL
  1852. Java_gnu_xml_libxmlj_dom_GnomeNode_lookupPrefix (JNIEnv * env, jobject self,
  1853. jstring namespaceURI)
  1854. {
  1855. xmlNodePtr node;
  1856. xmlNsPtr ns;
  1857. xmlDocPtr doc;
  1858. const xmlChar *s_uri;
  1859. node = xmljGetNodeID (env, self);
  1860. doc = node->doc;
  1861. /* If this is a document node, search from the root element */
  1862. if (node->type == XML_DOCUMENT_NODE)
  1863. {
  1864. doc = (xmlDocPtr) node;
  1865. node = xmlDocGetRootElement (doc);
  1866. }
  1867. s_uri = xmljGetStringChars (env, namespaceURI);
  1868. ns = xmlSearchNsByHref (doc, node, s_uri);
  1869. xmlFree ((xmlChar *) s_uri);
  1870. if (ns == NULL)
  1871. {
  1872. return NULL;
  1873. }
  1874. return xmljNewString (env, ns->prefix);
  1875. }
  1876. JNIEXPORT jboolean JNICALL
  1877. Java_gnu_xml_libxmlj_dom_GnomeNode_isDefaultNamespace (JNIEnv * env,
  1878. jobject self,
  1879. jstring namespaceURI)
  1880. {
  1881. xmlNodePtr node;
  1882. xmlNsPtr ns;
  1883. const xmlChar *s_uri;
  1884. node = xmljGetNodeID (env, self);
  1885. s_uri = xmljGetStringChars (env, namespaceURI);
  1886. ns = xmlSearchNsByHref (node->doc, node, s_uri);
  1887. xmlFree ((xmlChar *) s_uri);
  1888. if (ns == NULL)
  1889. {
  1890. return 0;
  1891. }
  1892. return (ns->prefix == NULL || xmlStrlen (ns->prefix) == 0);
  1893. }
  1894. JNIEXPORT jstring JNICALL
  1895. Java_gnu_xml_libxmlj_dom_GnomeNode_lookupNamespaceURI (JNIEnv * env,
  1896. jobject self,
  1897. jstring prefix)
  1898. {
  1899. xmlNodePtr node;
  1900. xmlDocPtr doc;
  1901. xmlNsPtr ns;
  1902. const xmlChar *s_prefix;
  1903. node = xmljGetNodeID (env, self);
  1904. doc = node->doc;
  1905. /* If this is a document node, search from the root element */
  1906. if (node->type == XML_DOCUMENT_NODE)
  1907. {
  1908. doc = (xmlDocPtr) node;
  1909. node = xmlDocGetRootElement (doc);
  1910. }
  1911. s_prefix = xmljGetStringChars (env, prefix);
  1912. ns = xmlSearchNs (doc, node, s_prefix);
  1913. xmlFree ((xmlChar *) s_prefix);
  1914. if (ns == NULL)
  1915. {
  1916. return NULL;
  1917. }
  1918. return xmljNewString (env, ns->href);
  1919. }
  1920. JNIEXPORT jint JNICALL
  1921. Java_gnu_xml_libxmlj_dom_GnomeNode_xmljCompareTo (JNIEnv * env,
  1922. jobject self,
  1923. jobject other)
  1924. {
  1925. xmlNodePtr n1, n2, x;
  1926. int d1, d2, delta, c;
  1927. n1 = xmljGetNodeID (env, self);
  1928. n2 = xmljGetNodeID (env, other);
  1929. if (n1->doc != n2->doc)
  1930. {
  1931. return 0;
  1932. }
  1933. if (n1->type == XML_ATTRIBUTE_NODE || n2->type == XML_ATTRIBUTE_NODE)
  1934. {
  1935. return 0;
  1936. }
  1937. d1 = 0;
  1938. for (x = n1->parent; x && x->type != XML_DOCUMENT_NODE; x = x->parent)
  1939. {
  1940. d1++;
  1941. }
  1942. d2 = 0;
  1943. for (x = n2->parent; x && x->type != XML_DOCUMENT_NODE; x = x->parent)
  1944. {
  1945. d2++;
  1946. }
  1947. delta = d1 - d2;
  1948. while (d1 > d2)
  1949. {
  1950. n1 = n1->parent;
  1951. d1--;
  1952. }
  1953. while (d2 > d1)
  1954. {
  1955. n2 = n2->parent;
  1956. d2--;
  1957. }
  1958. c = xmljCompare (n1, n2);
  1959. return (c != 0) ? c : delta;
  1960. }
  1961. /* Compare at same level */
  1962. int
  1963. xmljCompare (xmlNodePtr n1, xmlNodePtr n2)
  1964. {
  1965. int c, i1, i2;
  1966. if (n1->parent == NULL || n1->type == XML_DOCUMENT_NODE ||
  1967. n2->parent == NULL || n2->type == XML_DOCUMENT_NODE ||
  1968. n1 == n2)
  1969. {
  1970. return 0;
  1971. }
  1972. c = xmljCompare (n1->parent, n2->parent);
  1973. if (c != 0)
  1974. {
  1975. return c;
  1976. }
  1977. i1 = 0;
  1978. for (n1 = n1->prev; n1; n1 = n1->prev)
  1979. {
  1980. i1++;
  1981. }
  1982. i2 = 0;
  1983. for (n2 = n2->prev; n2; n2 = n2->prev)
  1984. {
  1985. i2++;
  1986. }
  1987. return i1 - i2;
  1988. }
  1989. int
  1990. xmljIsEqualNodeList (xmlNodePtr node1, xmlNodePtr node2)
  1991. {
  1992. while (node1 != NULL)
  1993. {
  1994. if (!xmljIsEqualNode (node1, node2))
  1995. {
  1996. return 0;
  1997. }
  1998. node1 = node1->next;
  1999. node2 = node2->next;
  2000. }
  2001. return 1;
  2002. }
  2003. int
  2004. xmljIsEqualNode (xmlNodePtr node1, xmlNodePtr node2)
  2005. {
  2006. const xmlChar *val1;
  2007. const xmlChar *val2;
  2008. if (node1 == node2)
  2009. {
  2010. return 1;
  2011. }
  2012. if (node1 == NULL || node2 == NULL)
  2013. {
  2014. return 0;
  2015. }
  2016. /* Check node type */
  2017. if (node1->type != node2->type)
  2018. {
  2019. return 0;
  2020. }
  2021. /* Check node name */
  2022. if (!xmlStrEqual (node1->name, node2->name))
  2023. {
  2024. return 0;
  2025. }
  2026. /* Check node namespace */
  2027. if (node1->type == XML_ELEMENT_NODE ||
  2028. node1->type == XML_ATTRIBUTE_NODE)
  2029. {
  2030. xmlNsPtr ns1, ns2;
  2031. ns1 = node1->ns;
  2032. if (ns1 != NULL)
  2033. {
  2034. ns2 = node2->ns;
  2035. if (ns2 == NULL)
  2036. {
  2037. return 0;
  2038. }
  2039. val1 = ns1->href;
  2040. val2 = ns2->href;
  2041. if (!xmlStrEqual (val1, val2))
  2042. {
  2043. return 0;
  2044. }
  2045. }
  2046. }
  2047. /* Check node value */
  2048. val1 = xmljGetNodeValue (node1);
  2049. val2 = xmljGetNodeValue (node2);
  2050. if (!xmlStrEqual (val1, val2))
  2051. {
  2052. return 0;
  2053. }
  2054. /* Check attributes */
  2055. if (node1->type == XML_ELEMENT_NODE &&
  2056. !xmljIsEqualNodeList ((xmlNodePtr) node1->properties,
  2057. (xmlNodePtr) node2->properties))
  2058. {
  2059. return 0;
  2060. }
  2061. /* Check doctype */
  2062. if (node1->type == XML_DOCUMENT_NODE)
  2063. {
  2064. xmlDocPtr doc1 = (xmlDocPtr) node1;
  2065. xmlDocPtr doc2 = (xmlDocPtr) node2;
  2066. if (!xmljIsEqualNode ((xmlNodePtr) doc1->intSubset,
  2067. (xmlNodePtr) doc2->intSubset) ||
  2068. !xmljIsEqualNode ((xmlNodePtr) doc1->extSubset,
  2069. (xmlNodePtr) doc2->extSubset))
  2070. {
  2071. return 0;
  2072. }
  2073. }
  2074. /* Check child nodes */
  2075. if (!xmljIsEqualNodeList (node1->children, node2->children))
  2076. {
  2077. return 0;
  2078. }
  2079. return 1;
  2080. }
  2081. JNIEXPORT jboolean JNICALL
  2082. Java_gnu_xml_libxmlj_dom_GnomeNode_isEqualNode (JNIEnv * env,
  2083. jobject self,
  2084. jobject arg)
  2085. {
  2086. xmlNodePtr node1;
  2087. xmlNodePtr node2;
  2088. node1 = xmljGetNodeID (env, self);
  2089. node2 = xmljGetNodeID (env, arg);
  2090. return xmljIsEqualNode (node1, node2);
  2091. }
  2092. /* -- GnomeNodeList -- */
  2093. JNIEXPORT jobject JNICALL
  2094. Java_gnu_xml_libxmlj_dom_GnomeNodeList_item (JNIEnv * env,
  2095. jobject self, jint index)
  2096. {
  2097. xmlNodePtr node;
  2098. jint count;
  2099. node = xmljGetNodeID (env, self);
  2100. node = node->children;
  2101. count = 0;
  2102. for (count = 0; node != NULL && count < index; count++)
  2103. {
  2104. node = node->next;
  2105. }
  2106. return xmljGetNodeInstance (env, node);
  2107. }
  2108. JNIEXPORT jint JNICALL
  2109. Java_gnu_xml_libxmlj_dom_GnomeNodeList_getLength (JNIEnv * env, jobject self)
  2110. {
  2111. xmlNodePtr node;
  2112. jint count;
  2113. node = xmljGetNodeID (env, self);
  2114. count = 0;
  2115. node = node->children;
  2116. while (node != NULL)
  2117. {
  2118. count++;
  2119. node = node->next;
  2120. }
  2121. return count;
  2122. }
  2123. /* -- GnomeNotation -- */
  2124. JNIEXPORT jstring JNICALL
  2125. Java_gnu_xml_libxmlj_dom_GnomeNotation_getPublicId (JNIEnv * env,
  2126. jobject self)
  2127. {
  2128. xmlNotationPtr notation;
  2129. notation = (xmlNotationPtr) xmljGetNodeID (env, self);
  2130. if (notation->PublicID == NULL)
  2131. {
  2132. return NULL;
  2133. }
  2134. return xmljNewString (env, notation->PublicID);
  2135. }
  2136. JNIEXPORT jstring JNICALL
  2137. Java_gnu_xml_libxmlj_dom_GnomeNotation_getSystemId (JNIEnv * env,
  2138. jobject self)
  2139. {
  2140. xmlNotationPtr notation;
  2141. notation = (xmlNotationPtr) xmljGetNodeID (env, self);
  2142. if (notation->SystemID == NULL)
  2143. {
  2144. return NULL;
  2145. }
  2146. return xmljNewString (env, notation->SystemID);
  2147. }
  2148. /* -- GnomeProcessingInstruction -- */
  2149. JNIEXPORT jstring JNICALL
  2150. Java_gnu_xml_libxmlj_dom_GnomeProcessingInstruction_getData (JNIEnv * env,
  2151. jobject self)
  2152. {
  2153. xmlNodePtr node;
  2154. xmlChar *text;
  2155. jstring ret;
  2156. node = xmljGetNodeID (env, self);
  2157. text = xmlNodeGetContent (node);
  2158. ret = xmljNewString (env, (const xmlChar *) text);
  2159. if (text != NULL)
  2160. {
  2161. xmlFree (text);
  2162. }
  2163. return ret;
  2164. }
  2165. JNIEXPORT void JNICALL
  2166. Java_gnu_xml_libxmlj_dom_GnomeProcessingInstruction_setData (JNIEnv * env,
  2167. jobject self,
  2168. jstring data)
  2169. {
  2170. xmlNodePtr node;
  2171. const xmlChar *s_data;
  2172. node = xmljGetNodeID (env, self);
  2173. s_data = xmljGetStringChars (env, data);
  2174. xmlNodeSetContent (node, s_data);
  2175. }
  2176. /* -- GnomeTypeInfo -- */
  2177. xmlDtdPtr xmljGetDtd (xmlDocPtr doc)
  2178. {
  2179. xmlNodePtr ctx;
  2180. for (ctx = doc->children; ctx; ctx = ctx->next)
  2181. {
  2182. if (ctx->type == XML_DOCUMENT_TYPE_NODE)
  2183. {
  2184. return (xmlDtdPtr) ctx;
  2185. }
  2186. }
  2187. return NULL;
  2188. }
  2189. JNIEXPORT jstring JNICALL
  2190. Java_gnu_xml_libxmlj_dom_GnomeTypeInfo_getTypeName (JNIEnv *env, jobject self)
  2191. {
  2192. xmlNodePtr node;
  2193. xmlDtdPtr dtd;
  2194. xmlAttributePtr attribute;
  2195. node = xmljGetNodeID (env, self);
  2196. dtd = xmljGetDtd (node->doc);
  2197. if (dtd)
  2198. {
  2199. switch (node->type)
  2200. {
  2201. case XML_ATTRIBUTE_NODE:
  2202. attribute = xmlGetDtdAttrDesc (dtd, node->parent->name, node->name);
  2203. if (attribute)
  2204. {
  2205. switch (attribute->type)
  2206. {
  2207. case XML_ATTRIBUTE_CDATA:
  2208. return xmljNewString (env, BAD_CAST "CDATA");
  2209. case XML_ATTRIBUTE_ID:
  2210. return xmljNewString (env, BAD_CAST "ID");
  2211. case XML_ATTRIBUTE_IDREF:
  2212. return xmljNewString (env, BAD_CAST "IDREF");
  2213. case XML_ATTRIBUTE_IDREFS:
  2214. return xmljNewString (env, BAD_CAST "IDREFS");
  2215. case XML_ATTRIBUTE_ENTITY:
  2216. return xmljNewString (env, BAD_CAST "ENTITY");
  2217. case XML_ATTRIBUTE_ENTITIES:
  2218. return xmljNewString (env, BAD_CAST "ENTITIES");
  2219. case XML_ATTRIBUTE_NMTOKEN:
  2220. return xmljNewString (env, BAD_CAST "NMTOKEN");
  2221. case XML_ATTRIBUTE_NMTOKENS:
  2222. return xmljNewString (env, BAD_CAST "NMTOKENS");
  2223. default:
  2224. return NULL;
  2225. }
  2226. }
  2227. return NULL;
  2228. default:
  2229. return NULL;
  2230. }
  2231. }
  2232. /* TODO when XML Schema support is available */
  2233. return NULL;
  2234. }
  2235. JNIEXPORT jstring JNICALL
  2236. Java_gnu_xml_libxmlj_dom_GnomeTypeInfo_getTypeNamespace (JNIEnv *env,
  2237. jobject self)
  2238. {
  2239. xmlNodePtr node;
  2240. xmlDtdPtr dtd;
  2241. xmlAttributePtr attribute;
  2242. node = xmljGetNodeID (env, self);
  2243. dtd = xmljGetDtd (node->doc);
  2244. if (dtd)
  2245. {
  2246. switch (node->type)
  2247. {
  2248. case XML_ATTRIBUTE_NODE:
  2249. attribute = xmlGetDtdAttrDesc (dtd, node->parent->name, node->name);
  2250. if (attribute)
  2251. {
  2252. return xmljNewString (env,
  2253. BAD_CAST "http://www.w3.org/TR/REC-xml");
  2254. }
  2255. return NULL;
  2256. default:
  2257. return NULL;
  2258. }
  2259. }
  2260. /* TODO when XML Schema support is available */
  2261. return NULL;
  2262. }
  2263. JNIEXPORT jboolean JNICALL
  2264. Java_gnu_xml_libxmlj_dom_GnomeTypeInfo_isDerivedFrom (JNIEnv *env
  2265. __attribute__ ((__unused__)),
  2266. jobject self
  2267. __attribute__ ((__unused__)),
  2268. jstring typeNS
  2269. __attribute__ ((__unused__)),
  2270. jstring typeName
  2271. __attribute__ ((__unused__)),
  2272. jint method
  2273. __attribute__ ((__unused__)))
  2274. {
  2275. /* TODO when XML Schema support is available */
  2276. return 0;
  2277. }
  2278. /* -- Utility -- */
  2279. /*
  2280. * Create GnomeDocument object from the given xmlDocPtr
  2281. */
  2282. jobject
  2283. xmljCreateDocument (JNIEnv * env, jobject self, xmlDocPtr doc)
  2284. {
  2285. jclass cls;
  2286. jfieldID field;
  2287. jobject ret;
  2288. if (!doc)
  2289. {
  2290. return NULL;
  2291. }
  2292. /* Get document object */
  2293. ret = xmljGetNodeInstance (env, (xmlNodePtr) doc);
  2294. /* Set DOM implementation field */
  2295. cls = (*env)->FindClass (env, "gnu/xml/libxmlj/dom/GnomeDocument");
  2296. field = (*env)->GetFieldID (env, cls, "dom",
  2297. "Lorg/w3c/dom/DOMImplementation;");
  2298. (*env)->SetObjectField (env, ret, field, self);
  2299. return ret;
  2300. }
  2301. xmlAttrPtr
  2302. xmljGetNamedItem (JNIEnv * env, jobject self, jstring name)
  2303. {
  2304. xmlNodePtr node;
  2305. xmlAttrPtr attr;
  2306. const xmlChar *s_name;
  2307. s_name = xmljGetStringChars (env, name);
  2308. node = xmljGetNodeID (env, self);
  2309. attr = node->properties;
  2310. while (attr != NULL)
  2311. {
  2312. if (xmljMatch (s_name, (xmlNodePtr) attr))
  2313. break;
  2314. attr = attr->next;
  2315. }
  2316. xmlFree ((xmlChar *) s_name);
  2317. return attr;
  2318. }
  2319. xmlAttrPtr
  2320. xmljGetNamedItemNS (JNIEnv * env, jobject self, jstring uri, jstring localName)
  2321. {
  2322. xmlNodePtr node;
  2323. xmlAttrPtr attr;
  2324. const xmlChar *s_uri;
  2325. const xmlChar *s_localName;
  2326. s_uri = xmljGetStringChars (env, uri);
  2327. s_localName = xmljGetStringChars (env, localName);
  2328. node = xmljGetNodeID (env, self);
  2329. attr = node->properties;
  2330. while (attr != NULL)
  2331. {
  2332. if (xmljMatchNS (s_uri, s_localName, (xmlNodePtr) attr))
  2333. break;
  2334. attr = attr->next;
  2335. }
  2336. xmlFree ((xmlChar *) s_uri);
  2337. xmlFree ((xmlChar *) s_localName);
  2338. return attr;
  2339. }