bool BaseBlock::submitValue(const Parser::name_stack_t& name_stack, Parser& p, bool silent) { if (!deserializeBlock(p, std::make_pair(name_stack.begin(), name_stack.end()))) { if (!silent) { p.parserWarning(llformat("Failed to parse parameter \"%s\"", p.getCurrentElementName().c_str())); } return false; } return true; }
void LLRNGWriter::writeAttribute(const std::string& type, const Parser::name_stack_t& stack, S32 min_count, S32 max_count, const std::vector<std::string>* possible_values) { if (max_count == 0) return; name_stack_t non_empty_names; std::string attribute_name; for (name_stack_t::const_iterator it = stack.begin(); it != stack.end(); ++it) { const std::string& name = it->first; if (!name.empty()) { non_empty_names.push_back(*it); } } if (non_empty_names.empty()) return; for (name_stack_t::const_iterator it = non_empty_names.begin(); it != non_empty_names.end(); ++it) { if (!attribute_name.empty()) { attribute_name += "."; } attribute_name += it->first; } // singular attribute, e.g. <foo bar="1"/> if (non_empty_names.size() == 1 && max_count == 1) { if (mAttributesWritten.second.find(attribute_name) == mAttributesWritten.second.end()) { LLXMLNodePtr node = createCardinalityNode(mElementNode, min_count, max_count)->createChild("attribute", false); node->createChild("name", true)->setStringValue(attribute_name); node->createChild("data", false)->createChild("type", true)->setStringValue(type); mAttributesWritten.second.insert(attribute_name); } } // compound attribute else { std::string element_name; // traverse all but last element, leaving that as an attribute name name_stack_t::const_iterator end_it = non_empty_names.end(); end_it--; for (name_stack_t::const_iterator it = non_empty_names.begin(); it != end_it; ++it) { if (it != non_empty_names.begin()) { element_name += "."; } element_name += it->first; } elements_map_t::iterator found_it = mElementsWritten.find(element_name); // <choice> // <group> // <optional> // <attribute name="foo.bar"><data type="string"/></attribute> // </optional> // <optional> // <attribute name="foo.baz"><data type="integer"/></attribute> // </optional> // </group> // <element name="foo"> // <optional> // <attribute name="bar"><data type="string"/></attribute> // </optional> // <optional> // <attribute name="baz"><data type="string"/></attribute> // </optional> // </element> // <element name="outer.foo"> // <ref name="foo"/> // </element> // </choice> if (found_it != mElementsWritten.end()) { // reuse existing element LLXMLNodePtr choice_node = found_it->second.first; // attribute with this name not already written? if (found_it->second.second.find(attribute_name) == found_it->second.second.end()) { // append to <group> LLXMLNodePtr node = choice_node->mChildren->head; node = createCardinalityNode(node, min_count, max_count)->createChild("attribute", false); node->createChild("name", true)->setStringValue(attribute_name); addTypeNode(node, type, possible_values); // append to <element> node = choice_node->mChildren->head->mNext->mChildren->head; node = createCardinalityNode(node, min_count, max_count)->createChild("attribute", false); node->createChild("name", true)->setStringValue(non_empty_names.back().first); addTypeNode(node, type, possible_values); // append to <element> //node = choice_node->mChildren->head->mNext->mNext->mChildren->head; //node = createCardinalityNode(node, min_count, max_count)->createChild("attribute", false); //node->createChild("name", true)->setStringValue(non_empty_names.back().first); //addTypeNode(node, type, possible_values); found_it->second.second.insert(attribute_name); } } else { LLXMLNodePtr choice_node = mElementNode->createChild("choice", false); LLXMLNodePtr node = choice_node->createChild("group", false); node = createCardinalityNode(node, min_count, max_count)->createChild("attribute", false); node->createChild("name", true)->setStringValue(attribute_name); addTypeNode(node, type, possible_values); node = choice_node->createChild("optional", false); node = node->createChild("element", false); node->createChild("name", true)->setStringValue(element_name); node = createCardinalityNode(node, min_count, max_count)->createChild("attribute", false); node->createChild("name", true)->setStringValue(non_empty_names.back().first); addTypeNode(node, type, possible_values); //node = choice_node->createChild("optional", false); //node = node->createChild("element", false); //node->createChild("name", true)->setStringValue(mDefinitionName + "." + element_name); //node = createCardinalityNode(node, min_count, max_count)->createChild("attribute", false); //node->createChild("name", true)->setStringValue(non_empty_names.back().first); //addTypeNode(node, type, possible_values); attribute_data_t& attribute_data = mElementsWritten[element_name]; attribute_data.first = choice_node; attribute_data.second.insert(attribute_name); } } }
void LLXSDWriter::writeAttribute(const std::string& type, const Parser::name_stack_t& stack, S32 min_count, S32 max_count, const std::vector<std::string>* possible_values) { name_stack_t non_empty_names; std::string attribute_name; for (name_stack_t::const_iterator it = stack.begin(); it != stack.end(); ++it) { const std::string& name = it->first; if (!name.empty()) { non_empty_names.push_back(*it); } } for (name_stack_t::const_iterator it = non_empty_names.begin(); it != non_empty_names.end(); ++it) { if (!attribute_name.empty()) { attribute_name += "."; } attribute_name += it->first; } // only flag non-nested attributes as mandatory, nested attributes have variant syntax // that can't be properly constrained in XSD // e.g. <foo mandatory.value="bar"/> vs <foo><mandatory value="bar"/></foo> bool attribute_mandatory = min_count == 1 && max_count == 1 && non_empty_names.size() == 1; // don't bother supporting "Multiple" params as xml attributes if (max_count <= 1) { // add compound attribute to root node addAttributeToSchema(mAttributeNode, attribute_name, type, attribute_mandatory, possible_values); } // now generated nested elements for compound attributes if (non_empty_names.size() > 1 && !attribute_mandatory) { std::string element_name; // traverse all but last element, leaving that as an attribute name name_stack_t::const_iterator end_it = non_empty_names.end(); end_it--; for (name_stack_t::const_iterator it = non_empty_names.begin(); it != end_it; ++it) { if (it != non_empty_names.begin()) { element_name += "."; } element_name += it->first; } std::string short_attribute_name = non_empty_names.back().first; LLXMLNodePtr complex_type_node; // find existing element node here, starting at tail of child list if (mElementNode->mChildren.notNull()) { for(LLXMLNodePtr element = mElementNode->mChildren->tail; element.notNull(); element = element->mPrev) { std::string name; if(element->getAttributeString("name", name) && name == element_name) { complex_type_node = element->mChildren->head; break; } } } //create complex_type node // //<xs:element // maxOccurs="1" // minOccurs="0" // name="name"> // <xs:complexType> // </xs:complexType> //</xs:element> if(complex_type_node.isNull()) { complex_type_node = mElementNode->createChild("xs:element", false); complex_type_node->createChild("minOccurs", true)->setIntValue(min_count); complex_type_node->createChild("maxOccurs", true)->setIntValue(max_count); complex_type_node->createChild("name", true)->setStringValue(element_name); complex_type_node = complex_type_node->createChild("xs:complexType", false); } addAttributeToSchema(complex_type_node, short_attribute_name, type, false, possible_values); } }