static void xemInstructionSetDocument ( __XProcHandlerArgs__ ) { if ( ! item.hasAttr(xem.href() ) ) { throwXemProcessorException ( "Instruction xem:set-document has no attribute xem:href\n" ); } if ( ! item.hasAttr(xem.select() ) ) { throwXemProcessorException ( "Instruction xem:set-document has no attribute xem:select\n" ); } String href = item.getEvaledAttr ( xproc, currentNode, xem.href() ); XPath selectXPath ( item, xem.select() ); NodeSet document; selectXPath.eval ( xproc, document, currentNode ); if ( ! document.isScalar() ) { throwXemProcessorException ( "Instruction xem:set-document : xem:select '%s' returns a non-scalar result !\n", item.getAttr (xem.select() ).c_str() ); } if ( ! document.front().isElement() ) { throwXemProcessorException ( "Instruction xem:set-document : xem:select '%s' returns a non-element result !\n", item.getAttr (xem.select() ).c_str() ); } ElementRef rootDocument = document.front().toElement(); xproc.setDocument ( href, rootDocument ); }
ElementDeclaration* DeclarationFactory::getDeclaration(Element* element__) { ElementDeclaration* resultElement; string elementName_ = element__->get_attribute_value("name"); NodeSet elementTypeSet = element__->find("@type"); if(!elementTypeSet.empty()) { FE_TRACE(__F(("DeclarationFactory::getDeclaration - Getting declaration for element %1%") % elementName_)); //we're getting an attribute type back, see xpath for @ Attribute* typeAttr = polymorphic_downcast<Attribute*>(elementTypeSet.front()); FE_TRACE(__F(("DeclarationFactory::getDeclaration - Element has type %1%") % typeAttr->get_value())); //checking if type is a basic type defined by the xsd definition //type should start with xs: if this is the namespace used for the xml schema definition if(typeAttr->get_value().substr(0, 3) == "xs:") { resultElement = new ElementDeclaration( elementName_, elementName_, createSimpleBaseTypeDeclaration(typeAttr->get_value()) ); } else { NodeSet typeSet = element__->find("//*[@name='"+typeAttr->get_value()+"']"); //shouldn't have to check if empty, otherwise invalid xsd Element* typeElement_ = polymorphic_downcast<Element*>(typeSet.front()); resultElement = createCustomTypeElementDeclaration(element__, typeElement_); } } else { FE_TRACE("DeclarationFactory::getDeclaration - Couldn't find attribute type so must be anonymous type"); //this means it's probably an anonymous type //first element should be the type //no children and no type attribute should invalid, so we can assume it has children NodeSet nodeSet = element__->find("*"); Element* typeElement_ = polymorphic_downcast<Element*>(nodeSet.front()); FE_TRACE(__F(("DeclarationFactory::getDeclaration - Tag name of the first child is %1%") % typeElement_->get_name() )); resultElement = createCustomTypeElementDeclaration(element__, typeElement_); } int minOccurs = 0; int maxOccurs = 1; string minOccursString = element__->get_attribute_value("minOccurs"); string maxOccursString = element__->get_attribute_value("maxOccurs"); if(maxOccursString == "unbounded"){ maxOccurs = INT_MAX; } else if (!maxOccursString.empty()) { maxOccurs = atoi(maxOccursString.c_str());} minOccurs = atoi(minOccursString.c_str()); FE_TRACE(__F(("DeclarationFactory::getDeclaration - Setting maxOccurs to %1%") % maxOccurs)); FE_TRACE(__F(("DeclarationFactory::getDeclaration - Setting minOccurs to %1%") % minOccurs)); resultElement->setMaxOccurs(maxOccurs); resultElement->setMinOccurs(minOccurs); return resultElement; }
AttributeDeclarationSet DeclarationFactory::extractAttributes(Element* element__) { FE_TRACE(__F(("DeclarationFactory::extractAttributes - Extracting attributes for element %1%") % element__->get_name() )); NodeSet attributeSet = element__->find("*[local-name() = 'attribute']"); AttributeDeclarationSet attributeResults; for(Node* n : attributeSet) { Element* attributeElem = polymorphic_downcast<Element*>(n); if(!attributeElem->get_attribute_value("ref").empty()){ continue; } FE_TRACE(__F(("DeclarationFactory::extractAttributes - Extracting attribute %1%") % attributeElem->get_attribute_value("name") )); TypeDeclaration* typeDeclaration_; if(attributeElem->get_attribute_value("type").substr(0, 3) == "xs:") { typeDeclaration_ = createSimpleBaseTypeDeclaration(attributeElem->get_attribute_value("type")); } else { NodeSet simpleTypeSet = element__->find("//*[@name = '"+attributeElem->get_attribute_value("type")+"']"); typeDeclaration_ = createSimpleTypeDeclaration(polymorphic_downcast<Element*>(simpleTypeSet.front())); } string name_ = attributeElem->get_attribute_value("name"); bool required_ = attributeElem->get_attribute_value("use") == "required" ? true : false; bool fixed_ = attributeElem->get_attribute_value("fixed").empty() ? false : true; string defaultValue_ = ""; if(fixed_){ defaultValue_ = attributeElem->get_attribute_value("fixed"); } else{ defaultValue_ = attributeElem->get_attribute_value("default"); } attributeResults.push_back( new AttributeDeclaration(name_, typeDeclaration_, required_, defaultValue_, fixed_) ); } return attributeResults; }
void XemProcessor::xemFunctionVariable ( __XProcFunctionArgs__ ) { if ( args.size() != 1 ) { throwXemProcessorException("Invalid number of arguments for xem:variable() !"); } NodeSet* ns = args[0]; if ( ns->size() != 1 ) { throwXemProcessorException("Invalid number of nodes for first argument of xem:variable() !"); } if ( ! ns->front().isAttribute() ) { throwXemProcessorException("Argument of xem:variable() is not an attribute !"); } AttributeRef attrRef = ns->front().toAttribute(); KeyId keyId = attrRef.getElement().getAttrAsKeyId(getXProcessor(),attrRef.getKeyId()); Log_XemCommon ( "Selected attr=%x\n", keyId ); NodeSet* variable = getXProcessor().getVariable(keyId); variable->copyTo(result); }
ElementDeclaration* XSDGuru::getElementDeclaration(string elementName__){ Element* rootElement = xsdParser.get_document()->get_root_node(); NodeSet elementDefinitionSet = rootElement->find("//*[local-name() = 'element' and @name='"+elementName__+"']"); if(!elementDefinitionSet.empty()){ Element* element_ = polymorphic_downcast<Element*>(elementDefinitionSet.front()); string elementName_ = element_->get_attribute_value("name"); if(!declarationCache.count(elementName_)){ unique_ptr<ElementDeclaration> elementShared_(DeclarationFactory::getDeclaration(element_)); declarationCache.insert( std::pair<string, unique_ptr<ElementDeclaration> >( elementName_, std::move(elementShared_) ) ); } return declarationCache[elementName_].get(); } else { FE_ERROR(__F(("XSDGuru::getElementDeclaration - Element with name %1% could not be found.") % elementName__)); } //return default constructor return 0; }
DoubleDeclaration::DoubleDeclaration(Element* typeDeclaration__) : NumericDeclaration<double>(typeDeclaration__->get_attribute_value("name")) { //extract info with xpath's //enumeration vector<string> enumStrings_ = extractEnumValues(typeDeclaration__); vector<double> enumValues_; for(string s : enumStrings_ ) { try { double tmp = lexical_cast<double>(s); enumValues_.push_back(tmp); } catch(bad_lexical_cast const& ){ continue; } } setEnumValues(enumValues_); //pattern setPattern(extractPattern(typeDeclaration__)); //min value string min_ = extractMin(typeDeclaration__); try { double tmp = lexical_cast<double>(min_); setMin(tmp); } catch(bad_lexical_cast const& ){ setMin(DBL_MIN); } //max value string max_ = extractMax(typeDeclaration__); try { double tmp = lexical_cast<double>(max_); setMax(tmp); } catch(bad_lexical_cast const& ){ setMax(DBL_MAX); } //total digits //probably won't be used just yet string totalDigits_ = extractTotalDigits(typeDeclaration__); try { int tmp = lexical_cast<int>(totalDigits_); setTotalDigits(tmp); } catch(bad_lexical_cast const& ){ setTotalDigits(DBL_DIG+DBL_MAX_10_EXP); } //double specific precision NodeSet precisionValueSet = typeDeclaration__->find(".//*[local-name() = 'fractionDigits']/@value"); int precision_; if(!precisionValueSet.empty()) { Attribute* attr = polymorphic_downcast<Attribute*>(precisionValueSet.front()); try { string tmp = attr->get_value(); precision_ = lexical_cast<int>(tmp); setPrecision(precision_); } catch(bad_lexical_cast const& ){ setPrecision(DBL_DIG); } } }
void XPath::evalFunctionKeyBuild ( ElementRef& baseElement, ElementMultiMapRef& map, XPath& matchXPath, XPath& useXPath, XPath& scopeXPath, KeyId mapId ) { bool recursive = true; // Warn !! Log_EvalKey ( "evalFunctionKeyBuild(baseElement=%s, match=%s, use=%s, scope=%s\n", baseElement.getKey().c_str(), matchXPath.expression, useXPath.expression, scopeXPath.expression); if ( ! recursive ) { Warn ( "Building key in a non-recursive mode ! This is against XSL specifications !\n" ); } if ( ! baseElement.getChild() ) { Log_EvalKey ( "Base element has no children !\n" ); return; } ElementRef current = baseElement; Log_EvalKey ( "Building Key !\n" ); Log_EvalKey ( "baseElement = '%s'\n", baseElement.getKey().c_str() ); Log_EvalKey ( "baseElement = '%s'\n", baseElement.generateVersatileXPath().c_str() ); __ui64 iterated = 0, found = 0; bool currentMatches; while ( true ) { Log_EvalKey ( "[At element %s (0x%llx:%x/%s), matching '%s' ?\n", current.generateVersatileXPath().c_str(), current.getElementId(), current.getKeyId(), current.getKey().c_str(), matchXPath.expression ); currentMatches = false; iterated++; if ( matchXPath.matches ( current ) ) { Log_EvalKey ( "Matches !\n" ); currentMatches = true; found++; if ( map ) { map.insert ( current, useXPath ); } else { NodeSet scopeNodeSet; scopeXPath.eval ( scopeNodeSet, current ); if ( scopeNodeSet.size() == 1 && scopeNodeSet.front().isElement() ) { ElementRef scopeElement = scopeNodeSet.toElement(); ElementMultiMapRef currentMap = scopeElement.findAttr ( mapId, AttributeType_SKMap ); if ( ! currentMap ) { Info ( "New skMap at '%s'\n", scopeElement.generateVersatileXPath().c_str() ); currentMap = scopeElement.addSKMap ( mapId, SKMapType_ElementMultiMap ); } Log_EvalKey ( "Inserting '%s'\n", current.generateVersatileXPath().c_str() ); currentMap.insert ( current, useXPath ); } else { Info ( "Silently ignoring '%s' : scope did not eval to an Element.\n", current.generateVersatileXPath().c_str() ); } } } if ( current.getChild() && ( !currentMatches || recursive ) ) { Log_EvalKey ( "Don't match, but has children.\n" ); current = current.getChild(); continue; } else { Log_EvalKey ( "Don't match, but no has child.\n" ); } while ( ! current.getYounger() ) { AssertBug ( current != baseElement, "How did I get there ?\n" ); current = current.getFather(); if ( ! current ) { throwException ( Exception, "Preliminary end of element !\n" ); } AssertBug ( current, "current had no father !\n" ); if ( current == baseElement ) { Log_EvalKey ( "Indexing finished : iterated over %llu, found %llu.\n", iterated, found ); return; } } current = current.getYounger (); } }