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
26 # include <libxml/tree.h>
29 #include "wine/debug.h"
31 WINE_DEFAULT_DEBUG_CHANNEL(msxml
);
33 /* Both XDR and XSD are valid XML
34 * We just convert the doc tree, no need for a parser.
39 static const xmlChar DT_prefix
[] = "dt";
40 static const xmlChar DT_href
[] = "urn:schemas-microsoft-com:datatypes";
41 static const xmlChar XDR_prefix
[] = "xdr";
42 static const xmlChar XDR_href
[] = "urn:schemas-microsoft-com:xml-data";
43 static const xmlChar XSD_prefix
[] = "xsd";
44 static const xmlChar XSD_href
[] = "http://www.w3.org/2001/XMLSchema";
46 static const xmlChar xs_all
[] = "all";
47 static const xmlChar xs_annotation
[] = "annotation";
48 static const xmlChar xs_any
[] = "any";
49 static const xmlChar xs_anyAttribute
[] = "anyAttribute";
50 static const xmlChar xs_attribute
[] = "attribute";
51 static const xmlChar xs_AttributeType
[] = "AttributeType";
52 static const xmlChar xs_base
[] = "base";
53 static const xmlChar xs_choice
[] = "choice";
54 static const xmlChar xs_complexContent
[] = "complexContent";
55 static const xmlChar xs_complexType
[] = "complexType";
56 static const xmlChar xs_content
[] = "content";
57 static const xmlChar xs_datatype
[] = "datatype";
58 static const xmlChar xs_default
[] = "default";
59 static const xmlChar xs_description
[] = "description";
60 static const xmlChar xs_documentation
[] = "documentation";
61 static const xmlChar xs_element
[] = "element";
62 static const xmlChar xs_ElementType
[] = "ElementType";
63 static const xmlChar xs_eltOnly
[] = "eltOnly";
64 static const xmlChar xs_empty
[] = "empty";
65 static const xmlChar xs_enumeration
[] = "enumeration";
66 static const xmlChar xs_extension
[] = "extension";
67 static const xmlChar xs_group
[] = "group";
68 static const xmlChar xs_lax
[] = "lax";
69 static const xmlChar xs_length
[] = "length";
70 static const xmlChar xs_many
[] = "many";
71 static const xmlChar xs_maxOccurs
[] = "maxOccurs";
72 static const xmlChar xs_minOccurs
[] = "minOccurs";
73 static const xmlChar xs_mixed
[] = "mixed";
74 static const xmlChar xs_model
[] = "model";
75 static const xmlChar xs_name
[] = "name";
76 static const xmlChar xs_namespace
[] = "namespace";
77 static const xmlChar xs_no
[] = "no";
78 static const xmlChar xs_one
[] = "one";
79 static const xmlChar xs_open
[] = "open";
80 static const xmlChar xs_optional
[] = "optional";
81 static const xmlChar xs_order
[] = "order";
82 static const xmlChar xs_processContents
[] = "processContents";
83 static const xmlChar xs_ref
[] = "ref";
84 static const xmlChar xs_required
[] = "required";
85 static const xmlChar xs_restriction
[] = "restriction";
86 static const xmlChar xs_schema
[] = "schema";
87 static const xmlChar xs_Schema
[] = "Schema";
88 static const xmlChar xs_seq
[] = "seq";
89 static const xmlChar xs_sequence
[] = "sequence";
90 static const xmlChar xs_simpleContent
[] = "simpleContent";
91 static const xmlChar xs_simpleType
[] = "simpleType";
92 static const xmlChar xs_strict
[] = "strict";
93 static const xmlChar xs_targetNamespace
[] = "targetNamespace";
94 static const xmlChar xs_textOnly
[] = "textOnly";
95 static const xmlChar xs_true
[] = "true";
96 static const xmlChar xs_type
[] = "type";
97 static const xmlChar xs_unbounded
[] = "unbounded";
98 static const xmlChar xs_use
[] = "use";
99 static const xmlChar xs_value
[] = "value";
100 static const xmlChar xs_values
[] = "values";
101 static const xmlChar xs_xsd_string
[] = "xsd:string";
102 static const xmlChar xs_yes
[] = "yes";
104 typedef enum _CONTENT_TYPE
112 typedef enum _ORDER_TYPE
119 #define FOREACH_CHILD(node, child) \
120 for (child = node->children; child != NULL; child = child->next) \
121 if (child->type == XML_ELEMENT_NODE)
123 #define FOREACH_ATTR(node, attr) \
124 for (attr = node->properties; attr != NULL; attr = attr->next)
126 #define FOREACH_NS(node, ns) \
127 for (ns = node->nsDef; ns != NULL; ns = ns->next)
129 static inline xmlNodePtr
get_schema(xmlNodePtr node
)
131 return xmlDocGetRootElement(node
->doc
);
134 static inline xmlNodePtr
get_child(xmlNodePtr node
, xmlChar
const* name
)
136 xmlNodePtr child
= NULL
;
139 FOREACH_CHILD(node
, child
)
141 if (xmlStrEqual(child
->name
, name
))
149 static inline xmlNodePtr
get_child_with_attr(xmlNodePtr node
, xmlChar
const* name
,
150 xmlChar
const* attr_ns
, xmlChar
const* attr_name
,
151 xmlChar
const* attr_val
)
156 FOREACH_CHILD(node
, node
)
158 if (xmlStrEqual(node
->name
, name
))
160 str
= (attr_ns
!= NULL
)? xmlGetNsProp(node
, attr_name
, attr_ns
) :
161 xmlGetProp(node
, attr_name
);
164 if (xmlStrEqual(str
, attr_val
))
178 static inline xmlNsPtr
get_dt_ns(xmlNodePtr node
)
182 node
= get_schema(node
);
183 assert(node
!= NULL
);
187 if (xmlStrEqual(ns
->href
, DT_href
))
194 static inline xmlChar
* get_dt_type(xmlNodePtr xdr
)
196 xmlChar
* str
= xmlGetNsProp(xdr
, xs_type
, DT_href
);
199 xmlNodePtr datatype
= get_child(xdr
, xs_datatype
);
201 str
= xmlGetNsProp(datatype
, xs_type
, DT_href
);
206 static inline xmlChar
* get_attr_val(xmlAttrPtr attr
)
208 return xmlNodeGetContent((xmlNodePtr
)attr
);
211 static inline xmlNodePtr
add_any_child(xmlNodePtr parent
, BOOL set_occurs
)
213 xmlNodePtr child
= xmlNewChild(parent
, NULL
, xs_any
, NULL
);
216 xmlSetProp(child
, xs_minOccurs
, BAD_CAST
"0");
217 xmlSetProp(child
, xs_maxOccurs
, xs_unbounded
);
219 xmlSetProp(child
, xs_processContents
, xs_strict
);
223 static inline xmlNodePtr
add_anyAttribute_child(xmlNodePtr parent
)
225 xmlNodePtr child
= xmlNewChild(parent
, NULL
, xs_anyAttribute
, NULL
);
226 xmlSetProp(child
, xs_processContents
, xs_lax
);
230 static inline xmlAttrPtr
copy_prop_ignore_ns(xmlAttrPtr xdr_attr
, xmlNodePtr node
)
232 xmlChar
* str
= get_attr_val(xdr_attr
);
233 xmlAttrPtr attr
= xmlSetProp(node
, xdr_attr
->name
, str
);
237 static inline xmlAttrPtr
XDR_A_default(xmlAttrPtr xdr_attr
, xmlNodePtr node
)
239 TRACE("(%p, %p)\n", xdr_attr
, node
);
241 return copy_prop_ignore_ns(xdr_attr
, node
);
244 static inline xmlAttrPtr
XDR_A_dt_type(xmlAttrPtr xdr_attr
, xmlNodePtr node
)
246 xmlChar
* str
= get_attr_val(xdr_attr
);
249 TRACE("(%p, %p)\n", xdr_attr
, node
);
251 if (xmlStrEqual(str
, xs_enumeration
))
254 attr
= xmlSetNsProp(node
, get_dt_ns(node
), DT_prefix
, str
);
259 static xmlAttrPtr
XDR_A_maxOccurs(xmlAttrPtr xdr_attr
, xmlNodePtr node
)
261 xmlChar
* str
= get_attr_val(xdr_attr
);
264 TRACE("(%p, %p)\n", xdr_attr
, node
);
266 if (xmlStrEqual(str
, BAD_CAST
"*"))
267 attr
= xmlSetProp(node
, xs_maxOccurs
, xs_unbounded
);
269 attr
= copy_prop_ignore_ns(xdr_attr
, node
);
275 static inline xmlAttrPtr
XDR_A_minOccurs(xmlAttrPtr xdr_attr
, xmlNodePtr node
)
277 TRACE("(%p, %p)\n", xdr_attr
, node
);
279 return copy_prop_ignore_ns(xdr_attr
, node
);
282 static inline xmlAttrPtr
XDR_A_name(xmlAttrPtr xdr_attr
, xmlNodePtr node
)
284 TRACE("(%p, %p)\n", xdr_attr
, node
);
286 return copy_prop_ignore_ns(xdr_attr
, node
);
289 static xmlAttrPtr
XDR_A_type(xmlAttrPtr xdr_attr
, xmlNodePtr node
)
291 xmlChar
* str
= get_attr_val(xdr_attr
);
292 xmlAttrPtr attr
= xmlSetProp(node
, xs_ref
, str
);
294 TRACE("(%p, %p)\n", xdr_attr
, node
);
300 static xmlAttrPtr
XDR_A_required(xmlAttrPtr xdr_attr
, xmlNodePtr node
)
302 xmlChar
* str
= get_attr_val(xdr_attr
);
305 TRACE("(%p, %p)\n", xdr_attr
, node
);
307 if (xmlStrEqual(str
, xs_no
))
308 attr
= xmlSetProp(node
, xs_use
, xs_optional
);
310 attr
= xmlSetProp(node
, xs_use
, xs_required
);
315 static xmlNodePtr
XDR_E_description(xmlNodePtr xdr
, xmlNodePtr parent
)
317 xmlNodePtr xsd_node
= xmlNewChild(parent
, NULL
, xs_annotation
, NULL
);
320 TRACE("(%p, %p)\n", xdr
, parent
);
322 xmlNewChild(xsd_node
, NULL
, xs_documentation
, xdr
->content
);
324 FOREACH_ATTR(xdr
, xdr_attr
)
326 xmlCopyProp(xsd_node
, xdr_attr
);
331 static xmlNodePtr
XDR_E_AttributeType(xmlNodePtr xdr
, xmlNodePtr parent
)
333 xmlChar
*str
, *type
= get_dt_type(xdr
);
334 xmlNodePtr xsd_node
, xsd_child
, xdr_child
;
337 TRACE("(%p, %p)\n", xdr
, parent
);
339 xsd_node
= xmlNewChild(parent
, NULL
, xs_attribute
, NULL
);
341 if (type
&& xmlStrEqual(type
, xs_enumeration
))
343 xmlChar
*tmp
, *tokBegin
, *tokEnd
= NULL
;
345 xsd_child
= xmlNewChild(xsd_node
, NULL
, xs_simpleType
, NULL
);
346 xsd_child
= xmlNewChild(xsd_child
, NULL
, xs_restriction
, NULL
);
347 xmlSetProp(xsd_child
, xs_base
, xs_xsd_string
);
349 tokBegin
= str
= xmlGetNsProp(xdr
, xs_values
, DT_href
);
350 while (tokBegin
&& *tokBegin
)
352 while (*tokBegin
&& isspace(*tokBegin
))
355 while (*tokEnd
&& !isspace(*tokEnd
))
357 if (tokEnd
== tokBegin
)
359 xsd_enum
= xmlNewChild(xsd_child
, NULL
, xs_enumeration
, NULL
);
360 tmp
= xmlStrndup(tokBegin
, tokEnd
-tokBegin
);
361 xmlSetProp(xsd_enum
, xs_value
, tmp
);
370 str
= xmlStrdup(DT_prefix
);
371 str
= xmlStrcat(str
, BAD_CAST
":");
372 str
= xmlStrcat(str
, type
);
373 xmlSetProp(xsd_node
, xs_type
, str
);
378 FOREACH_ATTR(xdr
, xdr_attr
)
380 if (xmlStrEqual(xdr_attr
->name
, xs_default
))
381 XDR_A_default(xdr_attr
, xsd_node
);
382 else if (xmlStrEqual(xdr_attr
->name
, xs_name
))
383 XDR_A_name(xdr_attr
, xsd_node
);
384 else if (xmlStrEqual(xdr_attr
->name
, xs_type
) && xdr_attr
->ns
== get_dt_ns(xdr
))
385 XDR_A_dt_type(xdr_attr
, xsd_node
);
386 else if (xmlStrEqual(xdr_attr
->name
, xs_values
) && xdr_attr
->ns
== get_dt_ns(xdr
))
387 ; /* already handled */
388 else if (xmlStrEqual(xdr_attr
->name
, xs_required
))
389 XDR_A_required(xdr_attr
, xsd_node
);
391 xmlCopyProp(xsd_node
, xdr_attr
);
394 FOREACH_CHILD(xdr
, xdr_child
)
396 if (xmlStrEqual(xdr_child
->name
, xs_datatype
))
397 ; /* already handled */
398 else if (xmlStrEqual(xdr_child
->name
, xs_description
))
399 XDR_E_description(xdr_child
, xsd_node
);
401 FIXME("unexpected child <%s>\n", xdr_child
->name
);
407 static xmlNodePtr
XDR_E_attribute(xmlNodePtr xdr
, xmlNodePtr parent
)
409 xmlChar
* str
= xmlGetProp(xdr
, xs_type
);
410 xmlNodePtr xsd_node
, xdr_child
, xdr_attrType
;
413 TRACE("(%p, %p)\n", xdr
, parent
);
415 xdr_attrType
= get_child_with_attr(xdr
->parent
, xs_AttributeType
, NULL
, xs_name
, str
);
419 xsd_node
= XDR_E_AttributeType(xdr_attrType
, parent
);
421 xsd_node
= xmlNewChild(parent
, NULL
, xs_attribute
, NULL
);
423 FOREACH_ATTR(xdr
, xdr_attr
)
425 if (xmlStrEqual(xdr_attr
->name
, xs_default
))
426 XDR_A_default(xdr_attr
, xsd_node
);
427 else if (xmlStrEqual(xdr_attr
->name
, xs_type
) && !xdr_attrType
)
428 XDR_A_type(xdr_attr
, xsd_node
);
429 else if (xmlStrEqual(xdr_attr
->name
, xs_required
))
430 XDR_A_required(xdr_attr
, xsd_node
);
432 xmlCopyProp(xsd_node
, xdr_attr
);
435 FOREACH_CHILD(xdr
, xdr_child
)
437 FIXME("unexpected child <%s>\n", xdr_child
->name
);
443 static xmlNodePtr
XDR_E_element(xmlNodePtr xdr
, xmlNodePtr parent
)
445 xmlNodePtr xdr_child
, xsd_node
= xmlNewChild(parent
, NULL
, xs_element
, NULL
);
448 FOREACH_ATTR(xdr
, xdr_attr
)
450 if (xmlStrEqual(xdr_attr
->name
, xs_type
))
451 XDR_A_type(xdr_attr
, xsd_node
);
452 else if (xmlStrEqual(xdr_attr
->name
, xs_maxOccurs
))
453 XDR_A_maxOccurs(xdr_attr
, xsd_node
);
454 else if (xmlStrEqual(xdr_attr
->name
, xs_minOccurs
))
455 XDR_A_minOccurs(xdr_attr
, xsd_node
);
457 xmlCopyProp(xsd_node
, xdr_attr
);
460 FOREACH_CHILD(xdr
, xdr_child
)
462 FIXME("unexpected child <%s>\n", xdr_child
->name
);
468 static xmlNodePtr
XDR_E_group(xmlNodePtr xdr
, xmlNodePtr parent
)
470 xmlNodePtr xdr_child
, xsd_node
;
471 xmlChar
* str
= xmlGetProp(xdr
, xs_order
);
474 TRACE("(%p, %p)\n", xdr
, parent
);
476 if (!str
|| xmlStrEqual(str
, xs_seq
))
477 xsd_node
= xmlNewChild(parent
, NULL
, xs_sequence
, NULL
);
478 else if (xmlStrEqual(str
, xs_many
))
479 xsd_node
= xmlNewChild(parent
, NULL
, xs_choice
, NULL
);
481 xsd_node
= xmlNewChild(parent
, NULL
, xs_all
, NULL
);
484 FOREACH_ATTR(xdr
, xdr_attr
)
486 if (xmlStrEqual(xdr_attr
->name
, xs_order
))
487 ; /* already handled */
488 else if (xmlStrEqual(xdr_attr
->name
, xs_model
))
490 else if (xmlStrEqual(xdr_attr
->name
, xs_maxOccurs
))
491 XDR_A_maxOccurs(xdr_attr
, xsd_node
);
492 else if (xmlStrEqual(xdr_attr
->name
, xs_minOccurs
))
493 XDR_A_minOccurs(xdr_attr
, xsd_node
);
495 xmlCopyProp(xsd_node
, xdr_attr
);
498 FOREACH_CHILD(xdr
, xdr_child
)
500 if (xmlStrEqual(xdr_child
->name
, xs_description
))
501 XDR_E_description(xdr_child
, xsd_node
);
502 else if (xmlStrEqual(xdr_child
->name
, xs_element
))
503 XDR_E_element(xdr_child
, xsd_node
);
509 static xmlNodePtr
XDR_E_ElementType(xmlNodePtr xdr
, xmlNodePtr parent
)
511 xmlChar
*str
, *type
= get_dt_type(xdr
);
513 int n_attributes
= 0, n_elements
= 0, n_groups
= 0;
514 CONTENT_TYPE content
;
516 xmlNodePtr xsd_node
, xsd_type
, xsd_child
, xdr_child
;
518 xmlNsPtr dt_ns
= get_dt_ns(parent
);
520 TRACE("(%p, %p)\n", xdr
, parent
);
522 str
= xmlGetProp(xdr
, xs_model
);
523 if (str
&& !xmlStrEqual(str
, xs_open
))
529 content
= CONTENT_TEXTONLY
;
533 str
= xmlGetProp(xdr
, xs_content
);
534 if (!str
|| xmlStrEqual(str
, xs_mixed
))
535 content
= CONTENT_MIXED
;
536 else if (xmlStrEqual(str
, xs_eltOnly
))
537 content
= CONTENT_ELTONLY
;
538 else if (xmlStrEqual(str
, xs_textOnly
))
539 content
= CONTENT_TEXTONLY
;
541 content
= CONTENT_EMPTY
;
545 str
= xmlGetProp(xdr
, xs_order
);
546 if (!str
|| xmlStrEqual(str
, xs_seq
))
550 else if (xmlStrEqual(str
, xs_many
))
561 FOREACH_CHILD(xdr
, xdr_child
)
563 if (xmlStrEqual(xdr_child
->name
, xs_element
))
565 else if (xmlStrEqual(xdr_child
->name
, xs_group
))
567 else if (xmlStrEqual(xdr_child
->name
, xs_attribute
))
571 xsd_node
= xmlNewChild(parent
, NULL
, xs_element
, NULL
);
572 assert(xsd_node
!= NULL
);
576 case CONTENT_ELTONLY
:
579 xsd_type
= xmlNewChild(xsd_node
, NULL
, xs_complexType
, NULL
);
581 if (content
== CONTENT_MIXED
)
582 xmlSetProp(xsd_type
, xs_mixed
, xs_true
);
585 xsd_base
= xmlNewChild(xsd_type
, NULL
, xs_sequence
, NULL
);
589 if (is_open
&& n_elements
< 2 && !n_groups
)
590 {/* no specific sequence of elements we need,
591 just has to start with the right one, if any */
592 if ((xdr_child
= get_child(xdr
, xs_element
)))
594 xsd_child
= XDR_E_element(xdr_child
, xsd_base
);
595 xmlUnsetProp(xsd_child
, xs_maxOccurs
);
603 xsd_child
= xmlNewChild(xsd_base
, NULL
, xs_sequence
, NULL
);
606 xsd_child
= xmlNewChild(xsd_base
, NULL
, xs_choice
, NULL
);
607 xmlSetProp(xsd_child
, xs_maxOccurs
, xs_unbounded
);
610 xsd_child
= xmlNewChild(xsd_base
, NULL
, xs_all
, NULL
);
614 FOREACH_CHILD(xdr
, xdr_child
)
616 if (xmlStrEqual(xdr_child
->name
, xs_element
))
617 XDR_E_element(xdr_child
, xsd_child
);
618 else if (xmlStrEqual(xdr_child
->name
, xs_group
))
619 XDR_E_group(xdr_child
, xsd_child
);
625 FOREACH_CHILD(xdr
, xdr_child
)
627 if (xmlStrEqual(xdr_child
->name
, xs_attribute
))
628 XDR_E_attribute(xdr_child
, xsd_type
);
634 add_any_child(xsd_base
, TRUE
);
635 add_anyAttribute_child(xsd_type
);
639 case CONTENT_TEXTONLY
:
643 xsd_type
= xmlNewChild(xsd_node
, NULL
, xs_complexType
, NULL
);
646 xsd_child
= xmlNewChild(xsd_type
, NULL
, xs_simpleContent
, NULL
);
647 xsd_child
= xmlNewChild(xsd_child
, NULL
, xs_extension
, NULL
);
648 str
= xmlStrdup(DT_prefix
);
649 str
= xmlStrcat(str
, BAD_CAST
":");
650 str
= xmlStrcat(str
, type
);
651 xmlSetProp(xsd_child
, xs_base
, str
);
653 assert(dt_ns
!= NULL
);
654 xmlSetNsProp(xsd_node
, dt_ns
, DT_prefix
, type
);
658 xmlSetProp(xsd_type
, xs_mixed
, xs_true
);
659 xsd_child
= xmlNewChild(xsd_type
, NULL
, xs_choice
, NULL
);
660 xmlSetProp(xsd_child
, xs_minOccurs
, BAD_CAST
"0");
661 xmlSetProp(xsd_child
, xs_maxOccurs
, xs_unbounded
);
662 xsd_child
= add_any_child(xsd_child
, FALSE
);
663 xmlSetProp(xsd_child
, xs_namespace
, BAD_CAST
"##other");
664 xsd_child
= xsd_type
;
668 FOREACH_CHILD(xdr
, xdr_child
)
670 if (xmlStrEqual(xdr_child
->name
, xs_attribute
))
671 XDR_E_attribute(xdr_child
, xsd_child
);
674 xmlNewChild(xsd_child
, NULL
, xs_anyAttribute
, NULL
);
676 else if (!n_attributes
)
680 str
= xmlStrdup(DT_prefix
);
681 str
= xmlStrcat(str
, BAD_CAST
":");
682 str
= xmlStrcat(str
, type
);
683 xmlSetProp(xsd_node
, xs_type
, str
);
686 xmlSetNsProp(xsd_node
, dt_ns
, DT_prefix
, type
);
690 xmlSetProp(xsd_node
, xs_type
, xs_xsd_string
);
695 xsd_type
= xmlNewChild(xsd_node
, NULL
, xs_complexType
, NULL
);
696 xsd_child
= xmlNewChild(xsd_type
, NULL
, xs_simpleContent
, NULL
);
697 xsd_child
= xmlNewChild(xsd_child
, NULL
, xs_extension
, NULL
);
698 xmlSetProp(xsd_child
, xs_base
, xs_xsd_string
);
700 FOREACH_CHILD(xdr
, xdr_child
)
702 if (xmlStrEqual(xdr_child
->name
, xs_attribute
))
703 XDR_E_attribute(xdr_child
, xsd_child
);
708 case CONTENT_EMPTY
: /* not allowed with model="open" */
712 xsd_type
= xmlNewChild(xsd_node
, NULL
, xs_complexType
, NULL
);
714 FOREACH_CHILD(xdr
, xdr_child
)
716 if (xmlStrEqual(xdr_child
->name
, xs_attribute
))
717 XDR_E_attribute(xdr_child
, xsd_type
);
722 xsd_type
= xmlNewChild(xsd_node
, NULL
, xs_simpleType
, NULL
);
723 xsd_child
= xmlNewChild(xsd_type
, NULL
, xs_restriction
, NULL
);
724 xmlSetProp(xsd_child
, xs_base
, xs_xsd_string
);
725 xsd_child
= xmlNewChild(xsd_child
, NULL
, xs_length
, NULL
);
726 xmlSetProp(xsd_child
, xs_value
, BAD_CAST
"0");
733 FOREACH_ATTR(xdr
, xdr_attr
)
735 if (xmlStrEqual(xdr_attr
->name
, xs_content
))
736 ; /* already handled */
737 else if (xmlStrEqual(xdr_attr
->name
, xs_name
))
738 XDR_A_name(xdr_attr
, xsd_node
);
739 else if (xmlStrEqual(xdr_attr
->name
, xs_type
) && xdr_attr
->ns
== get_dt_ns(xdr
))
740 XDR_A_dt_type(xdr_attr
, xsd_node
);
741 else if (xmlStrEqual(xdr_attr
->name
, xs_model
))
742 ; /* already handled */
743 else if (xmlStrEqual(xdr_attr
->name
, xs_order
))
744 ; /* already handled */
746 xmlCopyProp(xsd_node
, xdr_attr
);
750 FOREACH_CHILD(xdr
, xdr_child
)
752 if (xmlStrEqual(xdr_child
->name
, xs_attribute
))
753 ; /* already handled */
754 else if (xmlStrEqual(xdr_child
->name
, xs_AttributeType
))
755 ; /* handled through XDR_E_attribute when parent is not <Schema> */
756 else if (xmlStrEqual(xdr_child
->name
, xs_datatype
))
757 ; /* already handled */
758 else if (xmlStrEqual(xdr_child
->name
, xs_description
))
759 XDR_E_description(xdr_child
, xsd_node
);
760 else if (xmlStrEqual(xdr_child
->name
, xs_element
))
761 ; /* already handled */
762 else if (xmlStrEqual(xdr_child
->name
, xs_group
))
763 ; /* already handled */
765 FIXME("unexpected child <%s>\n", xdr_child
->name
);
771 static xmlNodePtr
XDR_E_Schema(xmlNodePtr xdr
, xmlNodePtr parent
, xmlChar
const* nsURI
)
773 xmlNodePtr xsd_node
, xdr_child
;
777 TRACE("(%p, %p)\n", xdr
, parent
);
779 xsd_node
= xmlNewDocNode((xmlDocPtr
)parent
, NULL
, xs_schema
, NULL
);
780 xmlDocSetRootElement((xmlDocPtr
)parent
, xsd_node
);
781 assert(xsd_node
!= NULL
);
783 if (nsURI
&& *nsURI
) xmlNewNs(xsd_node
, nsURI
, NULL
);
784 ns
= xmlNewNs(xsd_node
, XSD_href
, XSD_prefix
);
787 xmlSetNs(xsd_node
, ns
);
789 if (nsURI
&& *nsURI
) xmlSetProp(xsd_node
, xs_targetNamespace
, nsURI
);
791 FOREACH_NS(xdr
, xdr_ns
)
793 /* TODO: special handling for dt namespace? */
794 assert(xdr_ns
->href
!= NULL
);
795 if (xmlStrEqual(xdr_ns
->href
, XDR_href
))
797 else if (xdr_ns
->prefix
!= NULL
)
798 xmlNewNs(xsd_node
, xdr_ns
->href
, xdr_ns
->prefix
);
800 FIXME("unexpected default xmlns: %s\n", xdr_ns
->href
);
803 FOREACH_ATTR(xdr
, xdr_attr
)
805 xmlCopyProp(xsd_node
, xdr_attr
);
808 FOREACH_CHILD(xdr
, xdr_child
)
810 if (xmlStrEqual(xdr_child
->name
, xs_AttributeType
))
811 XDR_E_AttributeType(xdr_child
, xsd_node
);
812 else if (xmlStrEqual(xdr_child
->name
, xs_description
))
813 XDR_E_description(xdr_child
, xsd_node
);
814 else if (xmlStrEqual(xdr_child
->name
, xs_ElementType
))
815 XDR_E_ElementType(xdr_child
, xsd_node
);
817 FIXME("unexpected child <%s>\n", xdr_child
->name
);
823 xmlDocPtr
XDR_to_XSD_doc(xmlDocPtr xdr_doc
, xmlChar
const* nsURI
)
825 xmlDocPtr xsd_doc
= xmlNewDoc(NULL
);
827 TRACE("(%p)\n", xdr_doc
);
829 XDR_E_Schema(get_schema((xmlNodePtr
)xdr_doc
), (xmlNodePtr
)xsd_doc
, nsURI
);
834 #endif /* HAVE_LIBXML2 */