Thrift: Fix xsd:sequence and xsd:all minOccurs/maxOccurs generation
The minOccurs and maxOccurs attributes should appear on the elements, rather than the containers.
for a thrift struct, we produce:
<sequence>
<element name="some_element"> <!-- max is implicitly 1 -->
<element name="some_optional_element" minOccurs="0"> <!-- max is
implicitly 1 -->
...
for a thrift list, we produce
<sequence>
<element name="the_list_element" minOccurs="0" maxOccurs="unbounded">
</sequence>
for a thrift struct tagged with xsd_all, we produce
<all>
<element name="some_element" minOccurs="0"/> <!-- max is implicitly 1
-->
</all>
Reviewed By: mcslee
Test Plan: sandbox
Revert Plan: revertible
Notes:
git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@664962 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/compiler/cpp/src/generate/t_xsd_generator.cc b/compiler/cpp/src/generate/t_xsd_generator.cc
index 988aac8..7f53f9f 100644
--- a/compiler/cpp/src/generate/t_xsd_generator.cc
+++ b/compiler/cpp/src/generate/t_xsd_generator.cc
@@ -41,14 +41,14 @@
indent(s_xsd_types_) << "<xsd:complexType name=\"" << tstruct->get_name() << "\">" << endl;
indent_up();
if (xsd_all) {
- indent(s_xsd_types_) << "<xsd:all minOccurs=\"0\" maxOccurs=\"1\">" << endl;
+ indent(s_xsd_types_) << "<xsd:all>" << endl;
} else {
indent(s_xsd_types_) << "<xsd:sequence>" << endl;
}
indent_up();
for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
- generate_element(s_xsd_types_, (*m_iter)->get_name(), (*m_iter)->get_type(), (*m_iter)->get_xsd_optional());
+ generate_element(s_xsd_types_, (*m_iter)->get_name(), (*m_iter)->get_type(), (*m_iter)->get_xsd_optional() || xsd_all, false);
}
indent_down();
@@ -66,8 +66,12 @@
void t_xsd_generator::generate_element(ostream& out,
string name,
t_type* ttype,
- bool optional) {
- string soptional = optional ? " minOccurs=\"0\" maxOccurs=\"1\"" : "";
+ bool optional,
+ bool list_element) {
+ string sminOccurs = (optional || list_element) ? " minOccurs=\"0\"" : "";
+ string smaxOccurs = list_element ? " maxOccurs=\"unbounded\"" : "";
+
+ string soptional = sminOccurs + smaxOccurs;
if (ttype->is_void() || ttype->is_list()) {
indent(out) <<
@@ -79,7 +83,7 @@
} else if (ttype->is_list()) {
indent(out) << "<xsd:complexType>" << endl;
indent_up();
- indent(out) << "<xsd:sequence minOccurs=\"0\" maxOccurs=\"unbounded\">" << endl;
+ indent(out) << "<xsd:sequence>" << endl;
indent_up();
string subname;
t_type* subtype = ((t_list*)ttype)->get_elem_type();
@@ -89,7 +93,7 @@
subname = type_name(subtype);
}
f_php_ << "$GLOBALS['" << program_->get_name() << "_xsd_elt_" << name << "'] = '" << subname << "';" << endl;
- generate_element(out, subname, subtype);
+ generate_element(out, subname, subtype, false, true);
indent_down();
indent(out) << "</xsd:sequence>" << endl;
indent(out) << "<xsd:attribute name=\"list\" type=\"xsd:boolean\" />" << endl;
@@ -136,7 +140,7 @@
for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
string elemname = (*f_iter)->get_name() + "_response";
t_type* returntype = (*f_iter)->get_returntype();
- generate_element(f_xsd_, elemname, returntype);
+ generate_element(f_xsd_, elemname, returntype, false, false);
f_xsd_ << endl;
t_struct* xs = (*f_iter)->get_xceptions();
@@ -149,7 +153,7 @@
map<string, t_struct*>::iterator ax_iter;
for (ax_iter = all_xceptions.begin(); ax_iter != all_xceptions.end(); ++ax_iter) {
- generate_element(f_xsd_, ax_iter->first, ax_iter->second);
+ generate_element(f_xsd_, ax_iter->first, ax_iter->second, false, false);
}
// Close the XSD document
diff --git a/compiler/cpp/src/generate/t_xsd_generator.h b/compiler/cpp/src/generate/t_xsd_generator.h
index 0f6a41b..0413670 100644
--- a/compiler/cpp/src/generate/t_xsd_generator.h
+++ b/compiler/cpp/src/generate/t_xsd_generator.h
@@ -40,7 +40,7 @@
private:
- void generate_element(std::ostream& out, std::string name, t_type* ttype, bool optional=false);
+ void generate_element(std::ostream& out, std::string name, t_type* ttype, bool optional, bool list_element);
std::string ns(std::string in, std::string ns) {
return ns + ":" + in;