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
23 #include "wine/debug.h"
26 WINE_DEFAULT_DEBUG_CHANNEL(msxml
);
28 /* Both XDR and XSD are valid XML
29 * We just convert the doc tree, no need for a parser.
34 #include <libxml/tree.h>
36 static const xmlChar DT_prefix
[] = "dt";
37 static const xmlChar DT_href
[] = "urn:schemas-microsoft-com:datatypes";
38 static const xmlChar XDR_prefix
[] = "xdr";
39 static const xmlChar XDR_href
[] = "urn:schemas-microsoft-com:xml-data";
40 static const xmlChar XSD_prefix
[] = "xsd";
41 static const xmlChar XSD_href
[] = "http://www.w3.org/2001/XMLSchema";
43 static const xmlChar xs_all
[] = "all";
44 static const xmlChar xs_annotation
[] = "annotation";
45 static const xmlChar xs_any
[] = "any";
46 static const xmlChar xs_anyAttribute
[] = "anyAttribute";
47 static const xmlChar xs_attribute
[] = "attribute";
48 static const xmlChar xs_AttributeType
[] = "AttributeType";
49 static const xmlChar xs_base
[] = "base";
50 static const xmlChar xs_choice
[] = "choice";
51 static const xmlChar xs_complexContent
[] = "complexContent";
52 static const xmlChar xs_complexType
[] = "complexType";
53 static const xmlChar xs_content
[] = "content";
54 static const xmlChar xs_datatype
[] = "datatype";
55 static const xmlChar xs_default
[] = "default";
56 static const xmlChar xs_description
[] = "description";
57 static const xmlChar xs_documentation
[] = "documentation";
58 static const xmlChar xs_element
[] = "element";
59 static const xmlChar xs_ElementType
[] = "ElementType";
60 static const xmlChar xs_eltOnly
[] = "eltOnly";
61 static const xmlChar xs_empty
[] = "empty";
62 static const xmlChar xs_enumeration
[] = "enumeration";
63 static const xmlChar xs_extension
[] = "extension";
64 static const xmlChar xs_group
[] = "group";
65 static const xmlChar xs_lax
[] = "lax";
66 static const xmlChar xs_length
[] = "length";
67 static const xmlChar xs_many
[] = "many";
68 static const xmlChar xs_maxOccurs
[] = "maxOccurs";
69 static const xmlChar xs_minOccurs
[] = "minOccurs";
70 static const xmlChar xs_mixed
[] = "mixed";
71 static const xmlChar xs_model
[] = "model";
72 static const xmlChar xs_name
[] = "name";
73 static const xmlChar xs_namespace
[] = "namespace";
74 static const xmlChar xs_no
[] = "no";
75 static const xmlChar xs_one
[] = "one";
76 static const xmlChar xs_open
[] = "open";
77 static const xmlChar xs_optional
[] = "optional";
78 static const xmlChar xs_order
[] = "order";
79 static const xmlChar xs_processContents
[] = "processContents";
80 static const xmlChar xs_ref
[] = "ref";
81 static const xmlChar xs_required
[] = "required";
82 static const xmlChar xs_restriction
[] = "restriction";
83 static const xmlChar xs_schema
[] = "schema";
84 static const xmlChar xs_Schema
[] = "Schema";
85 static const xmlChar xs_seq
[] = "seq";
86 static const xmlChar xs_sequence
[] = "sequence";
87 static const xmlChar xs_simpleContent
[] = "simpleContent";
88 static const xmlChar xs_simpleType
[] = "simpleType";
89 static const xmlChar xs_strict
[] = "strict";
90 static const xmlChar xs_targetNamespace
[] = "targetNamespace";
91 static const xmlChar xs_textOnly
[] = "textOnly";
92 static const xmlChar xs_true
[] = "true";
93 static const xmlChar xs_type
[] = "type";
94 static const xmlChar xs_unbounded
[] = "unbounded";
95 static const xmlChar xs_use
[] = "use";
96 static const xmlChar xs_value
[] = "value";
97 static const xmlChar xs_values
[] = "values";
98 static const xmlChar xs_xsd_string
[] = "xsd:string";
99 static const xmlChar xs_yes
[] = "yes";
101 typedef enum _CONTENT_TYPE
109 typedef enum _ORDER_TYPE
116 #define FOREACH_CHILD(node, child) \
117 for (child = node->children; child != NULL; child = child->next) \
118 if (child->type == XML_ELEMENT_NODE)
120 #define FOREACH_ATTR(node, attr) \
121 for (attr = node->properties; attr != NULL; attr = attr->next)
123 #define FOREACH_NS(node, ns) \
124 for (ns = node->nsDef; ns != NULL; ns = ns->next)
126 static inline xmlNodePtr
get_schema(xmlNodePtr node
)
128 return xmlDocGetRootElement(node
->doc
);
131 static inline xmlNodePtr
get_child(xmlNodePtr node
, xmlChar
const* name
)
133 xmlNodePtr child
= NULL
;
136 FOREACH_CHILD(node
, child
)
138 if (xmlStrEqual(child
->name
, name
))
146 static inline xmlNodePtr
get_child_with_attr(xmlNodePtr node
, xmlChar
const* name
,
147 xmlChar
const* attr_ns
, xmlChar
const* attr_name
,
148 xmlChar
const* attr_val
)
153 FOREACH_CHILD(node
, node
)
155 if (xmlStrEqual(node
->name
, name
))
157 str
= (attr_ns
!= NULL
)? xmlGetNsProp(node
, attr_name
, attr_ns
) :
158 xmlGetProp(node
, attr_name
);
161 if (xmlStrEqual(str
, attr_val
))
175 static inline xmlNsPtr
get_dt_ns(xmlNodePtr node
)
179 node
= get_schema(node
);
180 assert(node
!= NULL
);
184 if (xmlStrEqual(ns
->href
, DT_href
))
191 static inline xmlChar
* get_dt_type(xmlNodePtr xdr
)
193 xmlChar
* str
= xmlGetNsProp(xdr
, xs_type
, DT_href
);
196 xmlNodePtr datatype
= get_child(xdr
, xs_datatype
);
198 str
= xmlGetNsProp(datatype
, xs_type
, DT_href
);
203 static inline xmlChar
* get_attr_val(xmlAttrPtr attr
)
205 return xmlNodeGetContent((xmlNodePtr
)attr
);
208 static inline xmlNodePtr
add_any_child(xmlNodePtr parent
, BOOL set_occurs
)
210 xmlNodePtr child
= xmlNewChild(parent
, NULL
, xs_any
, NULL
);
213 xmlSetProp(child
, xs_minOccurs
, BAD_CAST
"0");
214 xmlSetProp(child
, xs_maxOccurs
, xs_unbounded
);
216 xmlSetProp(child
, xs_processContents
, xs_strict
);
220 static inline xmlNodePtr
add_anyAttribute_child(xmlNodePtr parent
)
222 xmlNodePtr child
= xmlNewChild(parent
, NULL
, xs_anyAttribute
, NULL
);
223 xmlSetProp(child
, xs_processContents
, xs_lax
);
227 static inline xmlAttrPtr
copy_prop_ignore_ns(xmlAttrPtr xdr_attr
, xmlNodePtr node
)
229 xmlChar
* str
= get_attr_val(xdr_attr
);
230 xmlAttrPtr attr
= xmlSetProp(node
, xdr_attr
->name
, str
);
234 static inline xmlAttrPtr
XDR_A_default(xmlAttrPtr xdr_attr
, xmlNodePtr node
)
236 TRACE("(%p, %p)\n", xdr_attr
, node
);
238 return copy_prop_ignore_ns(xdr_attr
, node
);
241 static inline xmlAttrPtr
XDR_A_dt_type(xmlAttrPtr xdr_attr
, xmlNodePtr node
)
243 xmlChar
* str
= get_attr_val(xdr_attr
);
246 TRACE("(%p, %p)\n", xdr_attr
, node
);
248 if (xmlStrEqual(str
, xs_enumeration
))
251 attr
= xmlSetNsProp(node
, get_dt_ns(node
), DT_prefix
, str
);
256 static xmlAttrPtr
XDR_A_maxOccurs(xmlAttrPtr xdr_attr
, xmlNodePtr node
)
258 xmlChar
* str
= get_attr_val(xdr_attr
);
261 TRACE("(%p, %p)\n", xdr_attr
, node
);
263 if (xmlStrEqual(str
, BAD_CAST
"*"))
264 attr
= xmlSetProp(node
, xs_maxOccurs
, xs_unbounded
);
266 attr
= copy_prop_ignore_ns(xdr_attr
, node
);
272 static inline xmlAttrPtr
XDR_A_minOccurs(xmlAttrPtr xdr_attr
, xmlNodePtr node
)
274 TRACE("(%p, %p)\n", xdr_attr
, node
);
276 return copy_prop_ignore_ns(xdr_attr
, node
);
279 static inline xmlAttrPtr
XDR_A_name(xmlAttrPtr xdr_attr
, xmlNodePtr node
)
281 TRACE("(%p, %p)\n", xdr_attr
, node
);
283 return copy_prop_ignore_ns(xdr_attr
, node
);
286 static xmlAttrPtr
XDR_A_type(xmlAttrPtr xdr_attr
, xmlNodePtr node
)
288 xmlChar
* str
= get_attr_val(xdr_attr
);
289 xmlAttrPtr attr
= xmlSetProp(node
, xs_ref
, str
);
291 TRACE("(%p, %p)\n", xdr_attr
, node
);
297 static xmlAttrPtr
XDR_A_required(xmlAttrPtr xdr_attr
, xmlNodePtr node
)
299 xmlChar
* str
= get_attr_val(xdr_attr
);
302 TRACE("(%p, %p)\n", xdr_attr
, node
);
304 if (xmlStrEqual(str
, xs_no
))
305 attr
= xmlSetProp(node
, xs_use
, xs_optional
);
307 attr
= xmlSetProp(node
, xs_use
, xs_required
);
312 static xmlNodePtr
XDR_E_description(xmlNodePtr xdr
, xmlNodePtr parent
)
314 xmlNodePtr xsd_node
= xmlNewChild(parent
, NULL
, xs_annotation
, NULL
);
317 TRACE("(%p, %p)\n", xdr
, parent
);
319 xmlNewChild(xsd_node
, NULL
, xs_documentation
, xdr
->content
);
321 FOREACH_ATTR(xdr
, xdr_attr
)
323 xmlCopyProp(xsd_node
, xdr_attr
);
328 static xmlNodePtr
XDR_E_AttributeType(xmlNodePtr xdr
, xmlNodePtr parent
)
330 xmlChar
*str
, *type
= get_dt_type(xdr
);
331 xmlNodePtr xsd_node
, xsd_child
, xdr_child
;
334 TRACE("(%p, %p)\n", xdr
, parent
);
336 xsd_node
= xmlNewChild(parent
, NULL
, xs_attribute
, NULL
);
338 if (type
&& xmlStrEqual(type
, xs_enumeration
))
340 xmlChar
*tmp
, *tokBegin
, *tokEnd
= NULL
;
342 xsd_child
= xmlNewChild(xsd_node
, NULL
, xs_simpleType
, NULL
);
343 xsd_child
= xmlNewChild(xsd_child
, NULL
, xs_restriction
, NULL
);
344 xmlSetProp(xsd_child
, xs_base
, xs_xsd_string
);
346 tokBegin
= str
= xmlGetNsProp(xdr
, xs_values
, DT_href
);
347 while (tokBegin
&& *tokBegin
)
349 while (*tokBegin
&& isspace(*tokBegin
))
352 while (*tokEnd
&& !isspace(*tokEnd
))
354 if (tokEnd
== tokBegin
)
356 xsd_enum
= xmlNewChild(xsd_child
, NULL
, xs_enumeration
, NULL
);
357 tmp
= xmlStrndup(tokBegin
, tokEnd
-tokBegin
);
358 xmlSetProp(xsd_enum
, xs_value
, tmp
);
367 str
= xmlStrdup(DT_prefix
);
368 str
= xmlStrcat(str
, BAD_CAST
":");
369 str
= xmlStrcat(str
, type
);
370 xmlSetProp(xsd_node
, xs_type
, str
);
375 FOREACH_ATTR(xdr
, xdr_attr
)
377 if (xmlStrEqual(xdr_attr
->name
, xs_default
))
378 XDR_A_default(xdr_attr
, xsd_node
);
379 else if (xmlStrEqual(xdr_attr
->name
, xs_name
))
380 XDR_A_name(xdr_attr
, xsd_node
);
381 else if (xmlStrEqual(xdr_attr
->name
, xs_type
) && xdr_attr
->ns
== get_dt_ns(xdr
))
382 XDR_A_dt_type(xdr_attr
, xsd_node
);
383 else if (xmlStrEqual(xdr_attr
->name
, xs_values
) && xdr_attr
->ns
== get_dt_ns(xdr
))
384 ; /* already handled */
385 else if (xmlStrEqual(xdr_attr
->name
, xs_required
))
386 XDR_A_required(xdr_attr
, xsd_node
);
388 xmlCopyProp(xsd_node
, xdr_attr
);
391 FOREACH_CHILD(xdr
, xdr_child
)
393 if (xmlStrEqual(xdr_child
->name
, xs_datatype
))
394 ; /* already handled */
395 else if (xmlStrEqual(xdr_child
->name
, xs_description
))
396 XDR_E_description(xdr_child
, xsd_node
);
398 FIXME("unexpected child <%s>\n", xdr_child
->name
);
404 static xmlNodePtr
XDR_E_attribute(xmlNodePtr xdr
, xmlNodePtr parent
)
406 xmlChar
* str
= xmlGetProp(xdr
, xs_type
);
407 xmlNodePtr xsd_node
, xdr_child
, xdr_attrType
;
410 TRACE("(%p, %p)\n", xdr
, parent
);
412 xdr_attrType
= get_child_with_attr(xdr
->parent
, xs_AttributeType
, NULL
, xs_name
, str
);
416 xsd_node
= XDR_E_AttributeType(xdr_attrType
, parent
);
418 xsd_node
= xmlNewChild(parent
, NULL
, xs_attribute
, NULL
);
420 FOREACH_ATTR(xdr
, xdr_attr
)
422 if (xmlStrEqual(xdr_attr
->name
, xs_default
))
423 XDR_A_default(xdr_attr
, xsd_node
);
424 else if (xmlStrEqual(xdr_attr
->name
, xs_type
) && !xdr_attrType
)
425 XDR_A_type(xdr_attr
, xsd_node
);
426 else if (xmlStrEqual(xdr_attr
->name
, xs_required
))
427 XDR_A_required(xdr_attr
, xsd_node
);
429 xmlCopyProp(xsd_node
, xdr_attr
);
432 FOREACH_CHILD(xdr
, xdr_child
)
434 FIXME("unexpected child <%s>\n", xdr_child
->name
);
440 static xmlNodePtr
XDR_E_element(xmlNodePtr xdr
, xmlNodePtr parent
)
442 xmlNodePtr xdr_child
, xsd_node
= xmlNewChild(parent
, NULL
, xs_element
, NULL
);
445 FOREACH_ATTR(xdr
, xdr_attr
)
447 if (xmlStrEqual(xdr_attr
->name
, xs_type
))
448 XDR_A_type(xdr_attr
, xsd_node
);
449 else if (xmlStrEqual(xdr_attr
->name
, xs_maxOccurs
))
450 XDR_A_maxOccurs(xdr_attr
, xsd_node
);
451 else if (xmlStrEqual(xdr_attr
->name
, xs_minOccurs
))
452 XDR_A_minOccurs(xdr_attr
, xsd_node
);
454 xmlCopyProp(xsd_node
, xdr_attr
);
457 FOREACH_CHILD(xdr
, xdr_child
)
459 FIXME("unexpected child <%s>\n", xdr_child
->name
);
465 static xmlNodePtr
XDR_E_group(xmlNodePtr xdr
, xmlNodePtr parent
)
467 xmlNodePtr xdr_child
, xsd_node
;
468 xmlChar
* str
= xmlGetProp(xdr
, xs_order
);
471 TRACE("(%p, %p)\n", xdr
, parent
);
473 if (!str
|| xmlStrEqual(str
, xs_seq
))
474 xsd_node
= xmlNewChild(parent
, NULL
, xs_sequence
, NULL
);
475 else if (xmlStrEqual(str
, xs_many
))
476 xsd_node
= xmlNewChild(parent
, NULL
, xs_choice
, NULL
);
478 xsd_node
= xmlNewChild(parent
, NULL
, xs_all
, NULL
);
481 FOREACH_ATTR(xdr
, xdr_attr
)
483 if (xmlStrEqual(xdr_attr
->name
, xs_order
))
484 ; /* already handled */
485 else if (xmlStrEqual(xdr_attr
->name
, xs_model
))
487 else if (xmlStrEqual(xdr_attr
->name
, xs_maxOccurs
))
488 XDR_A_maxOccurs(xdr_attr
, xsd_node
);
489 else if (xmlStrEqual(xdr_attr
->name
, xs_minOccurs
))
490 XDR_A_minOccurs(xdr_attr
, xsd_node
);
492 xmlCopyProp(xsd_node
, xdr_attr
);
495 FOREACH_CHILD(xdr
, xdr_child
)
497 if (xmlStrEqual(xdr_child
->name
, xs_description
))
498 XDR_E_description(xdr_child
, xsd_node
);
499 else if (xmlStrEqual(xdr_child
->name
, xs_element
))
500 XDR_E_element(xdr_child
, xsd_node
);
506 static xmlNodePtr
XDR_E_ElementType(xmlNodePtr xdr
, xmlNodePtr parent
)
508 xmlChar
*str
, *type
= get_dt_type(xdr
);
510 int n_attributes
= 0, n_elements
= 0, n_groups
= 0;
511 CONTENT_TYPE content
;
513 xmlNodePtr xsd_node
, xsd_type
, xsd_child
, xdr_child
;
515 xmlNsPtr dt_ns
= get_dt_ns(parent
);
517 TRACE("(%p, %p)\n", xdr
, parent
);
519 str
= xmlGetProp(xdr
, xs_model
);
520 if (str
&& !xmlStrEqual(str
, xs_open
))
526 content
= CONTENT_TEXTONLY
;
530 str
= xmlGetProp(xdr
, xs_content
);
531 if (!str
|| xmlStrEqual(str
, xs_mixed
))
532 content
= CONTENT_MIXED
;
533 else if (xmlStrEqual(str
, xs_eltOnly
))
534 content
= CONTENT_ELTONLY
;
535 else if (xmlStrEqual(str
, xs_textOnly
))
536 content
= CONTENT_TEXTONLY
;
538 content
= CONTENT_EMPTY
;
542 str
= xmlGetProp(xdr
, xs_order
);
543 if (!str
|| xmlStrEqual(str
, xs_seq
))
547 else if (xmlStrEqual(str
, xs_many
))
558 FOREACH_CHILD(xdr
, xdr_child
)
560 if (xmlStrEqual(xdr_child
->name
, xs_element
))
562 else if (xmlStrEqual(xdr_child
->name
, xs_group
))
564 else if (xmlStrEqual(xdr_child
->name
, xs_attribute
))
568 xsd_node
= xmlNewChild(parent
, NULL
, xs_element
, NULL
);
569 assert(xsd_node
!= NULL
);
573 case CONTENT_ELTONLY
:
576 xsd_type
= xmlNewChild(xsd_node
, NULL
, xs_complexType
, NULL
);
578 if (content
== CONTENT_MIXED
)
579 xmlSetProp(xsd_type
, xs_mixed
, xs_true
);
582 xsd_base
= xmlNewChild(xsd_type
, NULL
, xs_sequence
, NULL
);
586 if (is_open
&& n_elements
< 2 && !n_groups
)
587 {/* no specific sequence of elements we need,
588 just has to start with the right one, if any */
589 if ((xdr_child
= get_child(xdr
, xs_element
)))
591 xsd_child
= XDR_E_element(xdr_child
, xsd_base
);
592 xmlUnsetProp(xsd_child
, xs_maxOccurs
);
600 xsd_child
= xmlNewChild(xsd_base
, NULL
, xs_sequence
, NULL
);
603 xsd_child
= xmlNewChild(xsd_base
, NULL
, xs_choice
, NULL
);
604 xmlSetProp(xsd_child
, xs_maxOccurs
, xs_unbounded
);
607 xsd_child
= xmlNewChild(xsd_base
, NULL
, xs_all
, NULL
);
611 FOREACH_CHILD(xdr
, xdr_child
)
613 if (xmlStrEqual(xdr_child
->name
, xs_element
))
614 XDR_E_element(xdr_child
, xsd_child
);
615 else if (xmlStrEqual(xdr_child
->name
, xs_group
))
616 XDR_E_group(xdr_child
, xsd_child
);
622 FOREACH_CHILD(xdr
, xdr_child
)
624 if (xmlStrEqual(xdr_child
->name
, xs_attribute
))
625 XDR_E_attribute(xdr_child
, xsd_type
);
631 add_any_child(xsd_base
, TRUE
);
632 add_anyAttribute_child(xsd_type
);
636 case CONTENT_TEXTONLY
:
640 xsd_type
= xmlNewChild(xsd_node
, NULL
, xs_complexType
, NULL
);
643 xsd_child
= xmlNewChild(xsd_type
, NULL
, xs_simpleContent
, NULL
);
644 xsd_child
= xmlNewChild(xsd_child
, NULL
, xs_extension
, NULL
);
645 str
= xmlStrdup(DT_prefix
);
646 str
= xmlStrcat(str
, BAD_CAST
":");
647 str
= xmlStrcat(str
, type
);
648 xmlSetProp(xsd_child
, xs_base
, str
);
650 assert(dt_ns
!= NULL
);
651 xmlSetNsProp(xsd_node
, dt_ns
, DT_prefix
, type
);
655 xmlSetProp(xsd_type
, xs_mixed
, xs_true
);
656 xsd_child
= xmlNewChild(xsd_type
, NULL
, xs_choice
, NULL
);
657 xmlSetProp(xsd_child
, xs_minOccurs
, BAD_CAST
"0");
658 xmlSetProp(xsd_child
, xs_maxOccurs
, xs_unbounded
);
659 xsd_child
= add_any_child(xsd_child
, FALSE
);
660 xmlSetProp(xsd_child
, xs_namespace
, BAD_CAST
"##other");
661 xsd_child
= xsd_type
;
665 FOREACH_CHILD(xdr
, xdr_child
)
667 if (xmlStrEqual(xdr_child
->name
, xs_attribute
))
668 XDR_E_attribute(xdr_child
, xsd_child
);
671 xmlNewChild(xsd_child
, NULL
, xs_anyAttribute
, NULL
);
673 else if (!n_attributes
)
677 str
= xmlStrdup(DT_prefix
);
678 str
= xmlStrcat(str
, BAD_CAST
":");
679 str
= xmlStrcat(str
, type
);
680 xmlSetProp(xsd_node
, xs_type
, str
);
683 xmlSetNsProp(xsd_node
, dt_ns
, DT_prefix
, type
);
687 xmlSetProp(xsd_node
, xs_type
, xs_xsd_string
);
692 xsd_type
= xmlNewChild(xsd_node
, NULL
, xs_complexType
, NULL
);
693 xsd_child
= xmlNewChild(xsd_type
, NULL
, xs_simpleContent
, NULL
);
694 xsd_child
= xmlNewChild(xsd_child
, NULL
, xs_extension
, NULL
);
695 xmlSetProp(xsd_child
, xs_base
, xs_xsd_string
);
697 FOREACH_CHILD(xdr
, xdr_child
)
699 if (xmlStrEqual(xdr_child
->name
, xs_attribute
))
700 XDR_E_attribute(xdr_child
, xsd_child
);
705 case CONTENT_EMPTY
: /* not allowed with model="open" */
709 xsd_type
= xmlNewChild(xsd_node
, NULL
, xs_complexType
, NULL
);
711 FOREACH_CHILD(xdr
, xdr_child
)
713 if (xmlStrEqual(xdr_child
->name
, xs_attribute
))
714 XDR_E_attribute(xdr_child
, xsd_type
);
719 xsd_type
= xmlNewChild(xsd_node
, NULL
, xs_simpleType
, NULL
);
720 xsd_child
= xmlNewChild(xsd_type
, NULL
, xs_restriction
, NULL
);
721 xmlSetProp(xsd_child
, xs_base
, xs_xsd_string
);
722 xsd_child
= xmlNewChild(xsd_child
, NULL
, xs_length
, NULL
);
723 xmlSetProp(xsd_child
, xs_value
, BAD_CAST
"0");
730 FOREACH_ATTR(xdr
, xdr_attr
)
732 if (xmlStrEqual(xdr_attr
->name
, xs_content
))
733 ; /* already handled */
734 else if (xmlStrEqual(xdr_attr
->name
, xs_name
))
735 XDR_A_name(xdr_attr
, xsd_node
);
736 else if (xmlStrEqual(xdr_attr
->name
, xs_type
) && xdr_attr
->ns
== get_dt_ns(xdr
))
737 XDR_A_dt_type(xdr_attr
, xsd_node
);
738 else if (xmlStrEqual(xdr_attr
->name
, xs_model
))
739 ; /* already handled */
740 else if (xmlStrEqual(xdr_attr
->name
, xs_order
))
741 ; /* already handled */
743 xmlCopyProp(xsd_node
, xdr_attr
);
747 FOREACH_CHILD(xdr
, xdr_child
)
749 if (xmlStrEqual(xdr_child
->name
, xs_attribute
))
750 ; /* already handled */
751 else if (xmlStrEqual(xdr_child
->name
, xs_AttributeType
))
752 ; /* handled through XDR_E_attribute when parent is not <Schema> */
753 else if (xmlStrEqual(xdr_child
->name
, xs_datatype
))
754 ; /* already handled */
755 else if (xmlStrEqual(xdr_child
->name
, xs_description
))
756 XDR_E_description(xdr_child
, xsd_node
);
757 else if (xmlStrEqual(xdr_child
->name
, xs_element
))
758 ; /* already handled */
759 else if (xmlStrEqual(xdr_child
->name
, xs_group
))
760 ; /* already handled */
762 FIXME("unexpected child <%s>\n", xdr_child
->name
);
768 static xmlNodePtr
XDR_E_Schema(xmlNodePtr xdr
, xmlNodePtr parent
, xmlChar
const* nsURI
)
770 xmlNodePtr xsd_node
, xdr_child
;
774 TRACE("(%p, %p)\n", xdr
, parent
);
776 xsd_node
= xmlNewDocNode((xmlDocPtr
)parent
, NULL
, xs_schema
, NULL
);
777 xmlDocSetRootElement((xmlDocPtr
)parent
, xsd_node
);
778 assert(xsd_node
!= NULL
);
780 if (nsURI
&& *nsURI
) xmlNewNs(xsd_node
, nsURI
, NULL
);
781 ns
= xmlNewNs(xsd_node
, XSD_href
, XSD_prefix
);
784 xmlSetNs(xsd_node
, ns
);
786 if (nsURI
&& *nsURI
) xmlSetProp(xsd_node
, xs_targetNamespace
, nsURI
);
788 FOREACH_NS(xdr
, xdr_ns
)
790 /* TODO: special handling for dt namespace? */
791 assert(xdr_ns
->href
!= NULL
);
792 if (xmlStrEqual(xdr_ns
->href
, XDR_href
))
794 else if (xdr_ns
->prefix
!= NULL
)
795 xmlNewNs(xsd_node
, xdr_ns
->href
, xdr_ns
->prefix
);
797 FIXME("unexpected default xmlns: %s\n", xdr_ns
->href
);
800 FOREACH_ATTR(xdr
, xdr_attr
)
802 xmlCopyProp(xsd_node
, xdr_attr
);
805 FOREACH_CHILD(xdr
, xdr_child
)
807 if (xmlStrEqual(xdr_child
->name
, xs_AttributeType
))
808 XDR_E_AttributeType(xdr_child
, xsd_node
);
809 else if (xmlStrEqual(xdr_child
->name
, xs_description
))
810 XDR_E_description(xdr_child
, xsd_node
);
811 else if (xmlStrEqual(xdr_child
->name
, xs_ElementType
))
812 XDR_E_ElementType(xdr_child
, xsd_node
);
814 FIXME("unexpected child <%s>\n", xdr_child
->name
);
820 xmlDocPtr
XDR_to_XSD_doc(xmlDocPtr xdr_doc
, xmlChar
const* nsURI
)
822 xmlDocPtr xsd_doc
= xmlNewDoc(NULL
);
824 TRACE("(%p)\n", xdr_doc
);
826 XDR_E_Schema(get_schema((xmlNodePtr
)xdr_doc
), (xmlNodePtr
)xsd_doc
, nsURI
);
831 #endif /* HAVE_LIBXML2 */