2 * XDR (XML-Data Reduced) -> XSD (XML Schema Document) conversion
4 * Copyright 2010 Adam Martinson for CodeWeavers
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
27 # include <libxml/tree.h>
30 /* Both XDR and XSD are valid XML
31 * We just convert the doc tree, no need for a parser.
36 static const xmlChar DT_prefix
[] = "dt";
37 static const xmlChar DT_href
[] = "urn:schemas-microsoft-com:datatypes";
38 static const xmlChar XDR_href
[] = "urn:schemas-microsoft-com:xml-data";
39 static const xmlChar XSD_prefix
[] = "xsd";
40 static const xmlChar XSD_href
[] = "http://www.w3.org/2001/XMLSchema";
42 static const xmlChar xs_all
[] = "all";
43 static const xmlChar xs_annotation
[] = "annotation";
44 static const xmlChar xs_any
[] = "any";
45 static const xmlChar xs_anyAttribute
[] = "anyAttribute";
46 static const xmlChar xs_attribute
[] = "attribute";
47 static const xmlChar xs_AttributeType
[] = "AttributeType";
48 static const xmlChar xs_base
[] = "base";
49 static const xmlChar xs_choice
[] = "choice";
50 static const xmlChar xs_complexType
[] = "complexType";
51 static const xmlChar xs_content
[] = "content";
52 static const xmlChar xs_datatype
[] = "datatype";
53 static const xmlChar xs_default
[] = "default";
54 static const xmlChar xs_description
[] = "description";
55 static const xmlChar xs_documentation
[] = "documentation";
56 static const xmlChar xs_element
[] = "element";
57 static const xmlChar xs_ElementType
[] = "ElementType";
58 static const xmlChar xs_eltOnly
[] = "eltOnly";
59 static const xmlChar xs_enumeration
[] = "enumeration";
60 static const xmlChar xs_extension
[] = "extension";
61 static const xmlChar xs_group
[] = "group";
62 static const xmlChar xs_lax
[] = "lax";
63 static const xmlChar xs_length
[] = "length";
64 static const xmlChar xs_many
[] = "many";
65 static const xmlChar xs_maxOccurs
[] = "maxOccurs";
66 static const xmlChar xs_minOccurs
[] = "minOccurs";
67 static const xmlChar xs_mixed
[] = "mixed";
68 static const xmlChar xs_model
[] = "model";
69 static const xmlChar xs_name
[] = "name";
70 static const xmlChar xs_namespace
[] = "namespace";
71 static const xmlChar xs_no
[] = "no";
72 static const xmlChar xs_open
[] = "open";
73 static const xmlChar xs_optional
[] = "optional";
74 static const xmlChar xs_order
[] = "order";
75 static const xmlChar xs_processContents
[] = "processContents";
76 static const xmlChar xs_ref
[] = "ref";
77 static const xmlChar xs_required
[] = "required";
78 static const xmlChar xs_restriction
[] = "restriction";
79 static const xmlChar xs_schema
[] = "schema";
80 static const xmlChar xs_seq
[] = "seq";
81 static const xmlChar xs_sequence
[] = "sequence";
82 static const xmlChar xs_simpleContent
[] = "simpleContent";
83 static const xmlChar xs_simpleType
[] = "simpleType";
84 static const xmlChar xs_strict
[] = "strict";
85 static const xmlChar xs_targetNamespace
[] = "targetNamespace";
86 static const xmlChar xs_textOnly
[] = "textOnly";
87 static const xmlChar xs_true
[] = "true";
88 static const xmlChar xs_type
[] = "type";
89 static const xmlChar xs_unbounded
[] = "unbounded";
90 static const xmlChar xs_use
[] = "use";
91 static const xmlChar xs_value
[] = "value";
92 static const xmlChar xs_values
[] = "values";
93 static const xmlChar xs_xsd_string
[] = "xsd:string";
95 typedef enum _CONTENT_TYPE
103 typedef enum _ORDER_TYPE
110 #define FOREACH_CHILD(node, child) \
111 for (child = node->children; child != NULL; child = child->next) \
112 if (child->type == XML_ELEMENT_NODE)
114 #define FOREACH_ATTR(node, attr) \
115 for (attr = node->properties; attr != NULL; attr = attr->next)
117 #define FOREACH_NS(node, ns) \
118 for (ns = node->nsDef; ns != NULL; ns = ns->next)
120 static inline xmlNodePtr
get_schema(xmlNodePtr node
)
122 return xmlDocGetRootElement(node
->doc
);
125 static inline xmlNodePtr
get_child(xmlNodePtr node
, xmlChar
const* name
)
127 xmlNodePtr child
= NULL
;
130 FOREACH_CHILD(node
, child
)
132 if (xmlStrEqual(child
->name
, name
))
140 static inline xmlNodePtr
get_child_with_attr(xmlNodePtr node
, xmlChar
const* name
,
141 xmlChar
const* attr_ns
, xmlChar
const* attr_name
,
142 xmlChar
const* attr_val
)
147 FOREACH_CHILD(node
, node
)
149 if (xmlStrEqual(node
->name
, name
))
151 str
= (attr_ns
!= NULL
)? xmlGetNsProp(node
, attr_name
, attr_ns
) :
152 xmlGetProp(node
, attr_name
);
155 if (xmlStrEqual(str
, attr_val
))
169 static inline xmlNsPtr
get_dt_ns(xmlNodePtr node
)
173 node
= get_schema(node
);
174 assert(node
!= NULL
);
178 if (xmlStrEqual(ns
->href
, DT_href
))
185 static inline xmlChar
* get_dt_type(xmlNodePtr xdr
)
187 xmlChar
* str
= xmlGetNsProp(xdr
, xs_type
, DT_href
);
190 xmlNodePtr datatype
= get_child(xdr
, xs_datatype
);
192 str
= xmlGetNsProp(datatype
, xs_type
, DT_href
);
197 static inline xmlChar
* get_attr_val(xmlAttrPtr attr
)
199 return xmlNodeGetContent((xmlNodePtr
)attr
);
202 static inline xmlNodePtr
add_any_child(xmlNodePtr parent
, BOOL set_occurs
)
204 xmlNodePtr child
= xmlNewChild(parent
, NULL
, xs_any
, NULL
);
207 xmlSetProp(child
, xs_minOccurs
, BAD_CAST
"0");
208 xmlSetProp(child
, xs_maxOccurs
, xs_unbounded
);
210 xmlSetProp(child
, xs_processContents
, xs_strict
);
214 static inline xmlNodePtr
add_anyAttribute_child(xmlNodePtr parent
)
216 xmlNodePtr child
= xmlNewChild(parent
, NULL
, xs_anyAttribute
, NULL
);
217 xmlSetProp(child
, xs_processContents
, xs_lax
);
221 static inline xmlAttrPtr
copy_prop_ignore_ns(xmlAttrPtr xdr_attr
, xmlNodePtr node
)
223 xmlChar
* str
= get_attr_val(xdr_attr
);
224 xmlAttrPtr attr
= xmlSetProp(node
, xdr_attr
->name
, str
);
228 static inline xmlAttrPtr
XDR_A_default(xmlAttrPtr xdr_attr
, xmlNodePtr node
)
230 TRACE("(%p, %p)\n", xdr_attr
, node
);
232 return copy_prop_ignore_ns(xdr_attr
, node
);
235 static inline xmlAttrPtr
XDR_A_dt_type(xmlAttrPtr xdr_attr
, xmlNodePtr node
)
237 xmlChar
* str
= get_attr_val(xdr_attr
);
240 TRACE("(%p, %p)\n", xdr_attr
, node
);
242 if (xmlStrEqual(str
, xs_enumeration
))
245 attr
= xmlSetNsProp(node
, get_dt_ns(node
), DT_prefix
, str
);
250 static xmlAttrPtr
XDR_A_maxOccurs(xmlAttrPtr xdr_attr
, xmlNodePtr node
)
252 xmlChar
* str
= get_attr_val(xdr_attr
);
255 TRACE("(%p, %p)\n", xdr_attr
, node
);
257 if (xmlStrEqual(str
, BAD_CAST
"*"))
258 attr
= xmlSetProp(node
, xs_maxOccurs
, xs_unbounded
);
260 attr
= copy_prop_ignore_ns(xdr_attr
, node
);
266 static inline xmlAttrPtr
XDR_A_minOccurs(xmlAttrPtr xdr_attr
, xmlNodePtr node
)
268 TRACE("(%p, %p)\n", xdr_attr
, node
);
270 return copy_prop_ignore_ns(xdr_attr
, node
);
273 static inline xmlAttrPtr
XDR_A_name(xmlAttrPtr xdr_attr
, xmlNodePtr node
)
275 TRACE("(%p, %p)\n", xdr_attr
, node
);
277 return copy_prop_ignore_ns(xdr_attr
, node
);
280 static xmlAttrPtr
XDR_A_type(xmlAttrPtr xdr_attr
, xmlNodePtr node
)
282 xmlChar
* str
= get_attr_val(xdr_attr
);
283 xmlAttrPtr attr
= xmlSetProp(node
, xs_ref
, str
);
285 TRACE("(%p, %p)\n", xdr_attr
, node
);
291 static xmlAttrPtr
XDR_A_required(xmlAttrPtr xdr_attr
, xmlNodePtr node
)
293 xmlChar
* str
= get_attr_val(xdr_attr
);
296 TRACE("(%p, %p)\n", xdr_attr
, node
);
298 if (xmlStrEqual(str
, xs_no
))
299 attr
= xmlSetProp(node
, xs_use
, xs_optional
);
301 attr
= xmlSetProp(node
, xs_use
, xs_required
);
306 static xmlNodePtr
XDR_E_description(xmlNodePtr xdr
, xmlNodePtr parent
)
308 xmlNodePtr xsd_node
= xmlNewChild(parent
, NULL
, xs_annotation
, NULL
);
311 TRACE("(%p, %p)\n", xdr
, parent
);
313 xmlNewChild(xsd_node
, NULL
, xs_documentation
, xdr
->content
);
315 FOREACH_ATTR(xdr
, xdr_attr
)
317 xmlCopyProp(xsd_node
, xdr_attr
);
322 static xmlNodePtr
XDR_E_AttributeType(xmlNodePtr xdr
, xmlNodePtr parent
)
324 xmlChar
*str
, *type
= get_dt_type(xdr
);
325 xmlNodePtr xsd_node
, xsd_child
, xdr_child
;
328 TRACE("(%p, %p)\n", xdr
, parent
);
330 xsd_node
= xmlNewChild(parent
, NULL
, xs_attribute
, NULL
);
332 if (type
&& xmlStrEqual(type
, xs_enumeration
))
334 xmlChar
*tmp
, *tokBegin
, *tokEnd
= NULL
;
336 xsd_child
= xmlNewChild(xsd_node
, NULL
, xs_simpleType
, NULL
);
337 xsd_child
= xmlNewChild(xsd_child
, NULL
, xs_restriction
, NULL
);
338 xmlSetProp(xsd_child
, xs_base
, xs_xsd_string
);
340 tokBegin
= str
= xmlGetNsProp(xdr
, xs_values
, DT_href
);
341 while (tokBegin
&& *tokBegin
)
343 while (*tokBegin
&& isspace(*tokBegin
))
346 while (*tokEnd
&& !isspace(*tokEnd
))
348 if (tokEnd
== tokBegin
)
350 xsd_enum
= xmlNewChild(xsd_child
, NULL
, xs_enumeration
, NULL
);
351 tmp
= xmlStrndup(tokBegin
, tokEnd
-tokBegin
);
352 xmlSetProp(xsd_enum
, xs_value
, tmp
);
361 str
= xmlStrdup(DT_prefix
);
362 str
= xmlStrcat(str
, BAD_CAST
":");
363 str
= xmlStrcat(str
, type
);
364 xmlSetProp(xsd_node
, xs_type
, str
);
369 FOREACH_ATTR(xdr
, xdr_attr
)
371 if (xmlStrEqual(xdr_attr
->name
, xs_default
))
372 XDR_A_default(xdr_attr
, xsd_node
);
373 else if (xmlStrEqual(xdr_attr
->name
, xs_name
))
374 XDR_A_name(xdr_attr
, xsd_node
);
375 else if (xmlStrEqual(xdr_attr
->name
, xs_type
) && xdr_attr
->ns
== get_dt_ns(xdr
))
376 XDR_A_dt_type(xdr_attr
, xsd_node
);
377 else if (xmlStrEqual(xdr_attr
->name
, xs_values
) && xdr_attr
->ns
== get_dt_ns(xdr
))
378 ; /* already handled */
379 else if (xmlStrEqual(xdr_attr
->name
, xs_required
))
380 XDR_A_required(xdr_attr
, xsd_node
);
382 xmlCopyProp(xsd_node
, xdr_attr
);
385 FOREACH_CHILD(xdr
, xdr_child
)
387 if (xmlStrEqual(xdr_child
->name
, xs_datatype
))
388 ; /* already handled */
389 else if (xmlStrEqual(xdr_child
->name
, xs_description
))
390 XDR_E_description(xdr_child
, xsd_node
);
392 FIXME("unexpected child <%s>\n", xdr_child
->name
);
398 static xmlNodePtr
XDR_E_attribute(xmlNodePtr xdr
, xmlNodePtr parent
)
400 xmlChar
* str
= xmlGetProp(xdr
, xs_type
);
401 xmlNodePtr xsd_node
, xdr_child
, xdr_attrType
;
404 TRACE("(%p, %p)\n", xdr
, parent
);
406 xdr_attrType
= get_child_with_attr(xdr
->parent
, xs_AttributeType
, NULL
, xs_name
, str
);
410 xsd_node
= XDR_E_AttributeType(xdr_attrType
, parent
);
412 xsd_node
= xmlNewChild(parent
, NULL
, xs_attribute
, NULL
);
414 FOREACH_ATTR(xdr
, xdr_attr
)
416 if (xmlStrEqual(xdr_attr
->name
, xs_default
))
417 XDR_A_default(xdr_attr
, xsd_node
);
418 else if (xmlStrEqual(xdr_attr
->name
, xs_type
) && !xdr_attrType
)
419 XDR_A_type(xdr_attr
, xsd_node
);
420 else if (xmlStrEqual(xdr_attr
->name
, xs_required
))
421 XDR_A_required(xdr_attr
, xsd_node
);
423 xmlCopyProp(xsd_node
, xdr_attr
);
426 FOREACH_CHILD(xdr
, xdr_child
)
428 FIXME("unexpected child <%s>\n", xdr_child
->name
);
434 static xmlNodePtr
XDR_E_element(xmlNodePtr xdr
, xmlNodePtr parent
)
436 xmlNodePtr xdr_child
, xsd_node
= xmlNewChild(parent
, NULL
, xs_element
, NULL
);
439 FOREACH_ATTR(xdr
, xdr_attr
)
441 if (xmlStrEqual(xdr_attr
->name
, xs_type
))
442 XDR_A_type(xdr_attr
, xsd_node
);
443 else if (xmlStrEqual(xdr_attr
->name
, xs_maxOccurs
))
444 XDR_A_maxOccurs(xdr_attr
, xsd_node
);
445 else if (xmlStrEqual(xdr_attr
->name
, xs_minOccurs
))
446 XDR_A_minOccurs(xdr_attr
, xsd_node
);
448 xmlCopyProp(xsd_node
, xdr_attr
);
451 FOREACH_CHILD(xdr
, xdr_child
)
453 FIXME("unexpected child <%s>\n", xdr_child
->name
);
459 static xmlNodePtr
XDR_E_group(xmlNodePtr xdr
, xmlNodePtr parent
)
461 xmlNodePtr xdr_child
, xsd_node
;
462 xmlChar
* str
= xmlGetProp(xdr
, xs_order
);
465 TRACE("(%p, %p)\n", xdr
, parent
);
467 if (!str
|| xmlStrEqual(str
, xs_seq
))
468 xsd_node
= xmlNewChild(parent
, NULL
, xs_sequence
, NULL
);
469 else if (xmlStrEqual(str
, xs_many
))
470 xsd_node
= xmlNewChild(parent
, NULL
, xs_choice
, NULL
);
472 xsd_node
= xmlNewChild(parent
, NULL
, xs_all
, NULL
);
475 FOREACH_ATTR(xdr
, xdr_attr
)
477 if (xmlStrEqual(xdr_attr
->name
, xs_order
))
478 ; /* already handled */
479 else if (xmlStrEqual(xdr_attr
->name
, xs_model
))
481 else if (xmlStrEqual(xdr_attr
->name
, xs_maxOccurs
))
482 XDR_A_maxOccurs(xdr_attr
, xsd_node
);
483 else if (xmlStrEqual(xdr_attr
->name
, xs_minOccurs
))
484 XDR_A_minOccurs(xdr_attr
, xsd_node
);
486 xmlCopyProp(xsd_node
, xdr_attr
);
489 FOREACH_CHILD(xdr
, xdr_child
)
491 if (xmlStrEqual(xdr_child
->name
, xs_description
))
492 XDR_E_description(xdr_child
, xsd_node
);
493 else if (xmlStrEqual(xdr_child
->name
, xs_element
))
494 XDR_E_element(xdr_child
, xsd_node
);
500 static xmlNodePtr
XDR_E_ElementType(xmlNodePtr xdr
, xmlNodePtr parent
)
502 xmlChar
*str
, *type
= get_dt_type(xdr
);
504 int n_attributes
= 0, n_elements
= 0, n_groups
= 0;
505 CONTENT_TYPE content
;
507 xmlNodePtr xsd_node
, xsd_type
, xsd_child
, xdr_child
;
509 xmlNsPtr dt_ns
= get_dt_ns(parent
);
511 TRACE("(%p, %p)\n", xdr
, parent
);
513 str
= xmlGetProp(xdr
, xs_model
);
514 if (str
&& !xmlStrEqual(str
, xs_open
))
520 content
= CONTENT_TEXTONLY
;
524 str
= xmlGetProp(xdr
, xs_content
);
525 if (!str
|| xmlStrEqual(str
, xs_mixed
))
526 content
= CONTENT_MIXED
;
527 else if (xmlStrEqual(str
, xs_eltOnly
))
528 content
= CONTENT_ELTONLY
;
529 else if (xmlStrEqual(str
, xs_textOnly
))
530 content
= CONTENT_TEXTONLY
;
532 content
= CONTENT_EMPTY
;
536 str
= xmlGetProp(xdr
, xs_order
);
537 if (!str
|| xmlStrEqual(str
, xs_seq
))
541 else if (xmlStrEqual(str
, xs_many
))
552 FOREACH_CHILD(xdr
, xdr_child
)
554 if (xmlStrEqual(xdr_child
->name
, xs_element
))
556 else if (xmlStrEqual(xdr_child
->name
, xs_group
))
558 else if (xmlStrEqual(xdr_child
->name
, xs_attribute
))
562 xsd_node
= xmlNewChild(parent
, NULL
, xs_element
, NULL
);
563 assert(xsd_node
!= NULL
);
567 case CONTENT_ELTONLY
:
570 xsd_type
= xmlNewChild(xsd_node
, NULL
, xs_complexType
, NULL
);
572 if (content
== CONTENT_MIXED
)
573 xmlSetProp(xsd_type
, xs_mixed
, xs_true
);
576 xsd_base
= xmlNewChild(xsd_type
, NULL
, xs_sequence
, NULL
);
580 if (is_open
&& n_elements
< 2 && !n_groups
)
581 {/* no specific sequence of elements we need,
582 just has to start with the right one, if any */
583 if ((xdr_child
= get_child(xdr
, xs_element
)))
585 xsd_child
= XDR_E_element(xdr_child
, xsd_base
);
586 xmlUnsetProp(xsd_child
, xs_maxOccurs
);
594 xsd_child
= xmlNewChild(xsd_base
, NULL
, xs_sequence
, NULL
);
597 xsd_child
= xmlNewChild(xsd_base
, NULL
, xs_choice
, NULL
);
598 xmlSetProp(xsd_child
, xs_maxOccurs
, xs_unbounded
);
601 xsd_child
= xmlNewChild(xsd_base
, NULL
, xs_all
, NULL
);
605 FOREACH_CHILD(xdr
, xdr_child
)
607 if (xmlStrEqual(xdr_child
->name
, xs_element
))
608 XDR_E_element(xdr_child
, xsd_child
);
609 else if (xmlStrEqual(xdr_child
->name
, xs_group
))
610 XDR_E_group(xdr_child
, xsd_child
);
616 FOREACH_CHILD(xdr
, xdr_child
)
618 if (xmlStrEqual(xdr_child
->name
, xs_attribute
))
619 XDR_E_attribute(xdr_child
, xsd_type
);
625 add_any_child(xsd_base
, TRUE
);
626 add_anyAttribute_child(xsd_type
);
630 case CONTENT_TEXTONLY
:
634 xsd_type
= xmlNewChild(xsd_node
, NULL
, xs_complexType
, NULL
);
637 xsd_child
= xmlNewChild(xsd_type
, NULL
, xs_simpleContent
, NULL
);
638 xsd_child
= xmlNewChild(xsd_child
, NULL
, xs_extension
, NULL
);
639 str
= xmlStrdup(DT_prefix
);
640 str
= xmlStrcat(str
, BAD_CAST
":");
641 str
= xmlStrcat(str
, type
);
642 xmlSetProp(xsd_child
, xs_base
, str
);
644 assert(dt_ns
!= NULL
);
645 xmlSetNsProp(xsd_node
, dt_ns
, DT_prefix
, type
);
649 xmlSetProp(xsd_type
, xs_mixed
, xs_true
);
650 xsd_child
= xmlNewChild(xsd_type
, NULL
, xs_choice
, NULL
);
651 xmlSetProp(xsd_child
, xs_minOccurs
, BAD_CAST
"0");
652 xmlSetProp(xsd_child
, xs_maxOccurs
, xs_unbounded
);
653 xsd_child
= add_any_child(xsd_child
, FALSE
);
654 xmlSetProp(xsd_child
, xs_namespace
, BAD_CAST
"##other");
655 xsd_child
= xsd_type
;
659 FOREACH_CHILD(xdr
, xdr_child
)
661 if (xmlStrEqual(xdr_child
->name
, xs_attribute
))
662 XDR_E_attribute(xdr_child
, xsd_child
);
665 xmlNewChild(xsd_child
, NULL
, xs_anyAttribute
, NULL
);
667 else if (!n_attributes
)
671 str
= xmlStrdup(DT_prefix
);
672 str
= xmlStrcat(str
, BAD_CAST
":");
673 str
= xmlStrcat(str
, type
);
674 xmlSetProp(xsd_node
, xs_type
, str
);
677 xmlSetNsProp(xsd_node
, dt_ns
, DT_prefix
, type
);
681 xmlSetProp(xsd_node
, xs_type
, xs_xsd_string
);
686 xsd_type
= xmlNewChild(xsd_node
, NULL
, xs_complexType
, NULL
);
687 xsd_child
= xmlNewChild(xsd_type
, NULL
, xs_simpleContent
, NULL
);
688 xsd_child
= xmlNewChild(xsd_child
, NULL
, xs_extension
, NULL
);
689 xmlSetProp(xsd_child
, xs_base
, xs_xsd_string
);
691 FOREACH_CHILD(xdr
, xdr_child
)
693 if (xmlStrEqual(xdr_child
->name
, xs_attribute
))
694 XDR_E_attribute(xdr_child
, xsd_child
);
699 case CONTENT_EMPTY
: /* not allowed with model="open" */
703 xsd_type
= xmlNewChild(xsd_node
, NULL
, xs_complexType
, NULL
);
705 FOREACH_CHILD(xdr
, xdr_child
)
707 if (xmlStrEqual(xdr_child
->name
, xs_attribute
))
708 XDR_E_attribute(xdr_child
, xsd_type
);
713 xsd_type
= xmlNewChild(xsd_node
, NULL
, xs_simpleType
, NULL
);
714 xsd_child
= xmlNewChild(xsd_type
, NULL
, xs_restriction
, NULL
);
715 xmlSetProp(xsd_child
, xs_base
, xs_xsd_string
);
716 xsd_child
= xmlNewChild(xsd_child
, NULL
, xs_length
, NULL
);
717 xmlSetProp(xsd_child
, xs_value
, BAD_CAST
"0");
724 FOREACH_ATTR(xdr
, xdr_attr
)
726 if (xmlStrEqual(xdr_attr
->name
, xs_content
))
727 ; /* already handled */
728 else if (xmlStrEqual(xdr_attr
->name
, xs_name
))
729 XDR_A_name(xdr_attr
, xsd_node
);
730 else if (xmlStrEqual(xdr_attr
->name
, xs_type
) && xdr_attr
->ns
== get_dt_ns(xdr
))
731 XDR_A_dt_type(xdr_attr
, xsd_node
);
732 else if (xmlStrEqual(xdr_attr
->name
, xs_model
))
733 ; /* already handled */
734 else if (xmlStrEqual(xdr_attr
->name
, xs_order
))
735 ; /* already handled */
737 xmlCopyProp(xsd_node
, xdr_attr
);
741 FOREACH_CHILD(xdr
, xdr_child
)
743 if (xmlStrEqual(xdr_child
->name
, xs_attribute
))
744 ; /* already handled */
745 else if (xmlStrEqual(xdr_child
->name
, xs_AttributeType
))
746 ; /* handled through XDR_E_attribute when parent is not <Schema> */
747 else if (xmlStrEqual(xdr_child
->name
, xs_datatype
))
748 ; /* already handled */
749 else if (xmlStrEqual(xdr_child
->name
, xs_description
))
750 XDR_E_description(xdr_child
, xsd_node
);
751 else if (xmlStrEqual(xdr_child
->name
, xs_element
))
752 ; /* already handled */
753 else if (xmlStrEqual(xdr_child
->name
, xs_group
))
754 ; /* already handled */
756 FIXME("unexpected child <%s>\n", xdr_child
->name
);
762 static xmlNodePtr
XDR_E_Schema(xmlNodePtr xdr
, xmlNodePtr parent
, xmlChar
const* nsURI
)
764 xmlNodePtr xsd_node
, xdr_child
;
768 TRACE("(%p, %p)\n", xdr
, parent
);
770 xsd_node
= xmlNewDocNode((xmlDocPtr
)parent
, NULL
, xs_schema
, NULL
);
771 xmlDocSetRootElement((xmlDocPtr
)parent
, xsd_node
);
772 assert(xsd_node
!= NULL
);
774 if (nsURI
&& *nsURI
) xmlNewNs(xsd_node
, nsURI
, NULL
);
775 ns
= xmlNewNs(xsd_node
, XSD_href
, XSD_prefix
);
778 xmlSetNs(xsd_node
, ns
);
780 if (nsURI
&& *nsURI
) xmlSetProp(xsd_node
, xs_targetNamespace
, nsURI
);
782 FOREACH_NS(xdr
, xdr_ns
)
784 /* TODO: special handling for dt namespace? */
785 assert(xdr_ns
->href
!= NULL
);
786 if (xmlStrEqual(xdr_ns
->href
, XDR_href
))
788 else if (xdr_ns
->prefix
!= NULL
)
789 xmlNewNs(xsd_node
, xdr_ns
->href
, xdr_ns
->prefix
);
791 FIXME("unexpected default xmlns: %s\n", xdr_ns
->href
);
794 FOREACH_ATTR(xdr
, xdr_attr
)
796 xmlCopyProp(xsd_node
, xdr_attr
);
799 FOREACH_CHILD(xdr
, xdr_child
)
801 if (xmlStrEqual(xdr_child
->name
, xs_AttributeType
))
802 XDR_E_AttributeType(xdr_child
, xsd_node
);
803 else if (xmlStrEqual(xdr_child
->name
, xs_description
))
804 XDR_E_description(xdr_child
, xsd_node
);
805 else if (xmlStrEqual(xdr_child
->name
, xs_ElementType
))
806 XDR_E_ElementType(xdr_child
, xsd_node
);
808 FIXME("unexpected child <%s>\n", xdr_child
->name
);
814 xmlDocPtr
XDR_to_XSD_doc(xmlDocPtr xdr_doc
, xmlChar
const* nsURI
)
816 xmlDocPtr xsd_doc
= xmlNewDoc(NULL
);
818 TRACE("(%p)\n", xdr_doc
);
820 XDR_E_Schema(get_schema((xmlNodePtr
)xdr_doc
), (xmlNodePtr
)xsd_doc
, nsURI
);
825 #endif /* HAVE_LIBXML2 */