private void process(IElement node, bool root) { IList<RDFa.IncompleteTriple> incompleteTriplesLocal=new List<RDFa.IncompleteTriple>(); string localLanguage=context.language; RDFTerm newSubject=null; bool recurse=true; bool skipElement=false; RDFTerm currentObject=null; IDictionary<string,string> namespacesLocal= new PeterO.Support.LenientDictionary<string,string>(context.namespaces); IDictionary<string,string> iriMapLocal= new PeterO.Support.LenientDictionary<string,string>(context.iriMap); string attr=null; if(!xhtml){ attr=node.getAttribute("xml:base"); if(attr!=null){ context.baseURI=URIUtility.relativeResolve(attr, context.baseURI); } } // Support XML namespaces foreach(var attrib in node.getAttributes()){ string name=StringUtility.toLowerCaseAscii(attrib.getName()); //Console.WriteLine(attrib); if(name.Equals("xmlns")){ //Console.WriteLine("xmlns %s",attrib.getValue()); iriMapLocal.Add("", attrib.getValue()); namespacesLocal.Add("", attrib.getValue()); } else if(name.StartsWith("xmlns:",StringComparison.Ordinal) && name.Length>6){ string prefix=name.Substring(6); //Console.WriteLine("xmlns %s %s",prefix,attrib.getValue()); if(!"_".Equals(prefix)){ iriMapLocal.Add(prefix, attrib.getValue()); } namespacesLocal.Add(prefix, attrib.getValue()); } } attr=node.getAttribute("xml:lang"); if(attr!=null){ localLanguage=attr; } // Support RDF/XML metadata if(node.getLocalName().Equals("RDF") && RDF_NAMESPACE.Equals(node.getNamespaceURI())){ miniRdfXml(node,context); return; } string rel=node.getAttribute("rel"); string rev=node.getAttribute("rev"); string property=node.getAttribute("property"); string content=node.getAttribute("content"); string datatype=node.getAttribute("datatype"); if(rel==null && rev==null){ // Step 4 RDFTerm resource=getSafeCurieOrCurieOrIri( node.getAttribute("about"),iriMapLocal); if(resource==null){ resource=getSafeCurieOrCurieOrIri( node.getAttribute("resource"),iriMapLocal); } if(resource==null){ resource=relativeResolve(node.getAttribute("href")); } if(resource==null){ resource=relativeResolve(node.getAttribute("src")); } if((resource==null || resource.getKind()!=RDFTerm.IRI)){ string rdfTypeof=getCurie(node.getAttribute("typeof"),iriMapLocal); if(isHtmlElement(node, "head") || isHtmlElement(node, "body")){ resource=getSafeCurieOrCurieOrIri("",iriMapLocal); } if(resource==null && !xhtml && root){ resource=getSafeCurieOrCurieOrIri("",iriMapLocal); } if(resource==null && rdfTypeof!=null){ resource=generateBlankNode(); } if(resource==null){ if(context.parentObject!=null) { resource=context.parentObject; } if(node.getAttribute("property")==null){ skipElement=true; } } newSubject=resource; } else { newSubject=resource; } } else { // Step 5 RDFTerm resource=getSafeCurieOrCurieOrIri( node.getAttribute("about"),iriMapLocal); if(resource==null){ resource=relativeResolve(node.getAttribute("src")); } if((resource==null || resource.getKind()!=RDFTerm.IRI)){ string rdfTypeof=getCurie(node.getAttribute("typeof"),iriMapLocal); if(isHtmlElement(node, "head") || isHtmlElement(node, "body")){ resource=getSafeCurieOrCurieOrIri("",iriMapLocal); } if(resource==null && !xhtml && root){ resource=getSafeCurieOrCurieOrIri("",iriMapLocal); } if(resource==null && rdfTypeof!=null){ resource=generateBlankNode(); } if(resource==null){ if(context.parentObject!=null) { resource=context.parentObject; } } newSubject=resource; } else { newSubject=resource; } resource=getSafeCurieOrCurieOrIri( node.getAttribute("resource"),iriMapLocal); if(resource==null){ resource=relativeResolve(node.getAttribute("href")); } currentObject=resource; } // Step 6 if(newSubject!=null){ string[] types=StringUtility.splitAtNonFFSpaces(node.getAttribute("typeof")); foreach(var type in types){ string iri=getCurie(type,iriMapLocal); if(iri!=null){ outputGraph.Add(new RDFTriple( newSubject,RDFTerm.A, RDFTerm.fromIRI(iri) )); } } } // Step 7 if(currentObject!=null){ string[] types=StringUtility.splitAtNonFFSpaces(rel); foreach(var type in types){ string iri=getRelTermOrCurie(type, iriMapLocal); #if DEBUG if(!(newSubject!=null))throw new InvalidOperationException("doesn't satisfy newSubject!=null"); #endif if(iri!=null){ outputGraph.Add(new RDFTriple( newSubject, RDFTerm.fromIRI(iri),currentObject )); } } types=StringUtility.splitAtNonFFSpaces(rev); foreach(var type in types){ string iri=getRelTermOrCurie(type, iriMapLocal); if(iri!=null){ outputGraph.Add(new RDFTriple( currentObject, RDFTerm.fromIRI(iri), newSubject )); } } } else { // Step 8 string[] types=StringUtility.splitAtNonFFSpaces(rel); bool hasPredicates=false; // Defines predicates foreach(var type in types){ string iri=getRelTermOrCurie(type, iriMapLocal); if(iri!=null){ if(!hasPredicates){ hasPredicates=true; currentObject=generateBlankNode(); } RDFa.IncompleteTriple inc=new RDFa.IncompleteTriple(); inc.predicate=RDFTerm.fromIRI(iri); inc.direction=RDFa.ChainingDirection.Forward; incompleteTriplesLocal.Add(inc); } } types=StringUtility.splitAtNonFFSpaces(rev); foreach(var type in types){ string iri=getRelTermOrCurie(type, iriMapLocal); if(iri!=null){ if(!hasPredicates){ hasPredicates=true; currentObject=generateBlankNode(); } RDFa.IncompleteTriple inc=new RDFa.IncompleteTriple(); inc.predicate=RDFTerm.fromIRI(iri); inc.direction=RDFa.ChainingDirection.Reverse; incompleteTriplesLocal.Add(inc); } } } // Step 9 string[] preds=StringUtility.splitAtNonFFSpaces(property); string datatypeValue=getCurie(datatype, iriMapLocal); if(datatype!=null && datatypeValue==null) { datatypeValue=""; } //Console.WriteLine("datatype=[%s] prop=%s vocab=%s", // datatype,property,localDefaultVocab); //Console.WriteLine("datatypeValue=[%s]",datatypeValue); RDFTerm currentProperty=null; foreach(var pred in preds){ string iri=getCurie(pred, iriMapLocal); if(iri!=null){ //Console.WriteLine("iri=[%s]",iri); currentProperty=null; if(datatypeValue!=null && datatypeValue.Length>0 && !datatypeValue.Equals(RDF_XMLLITERAL)){ string literal=content; if(literal==null) { literal=getTextNodeText(node); } currentProperty=RDFTerm.fromTypedString(literal,datatypeValue); } else if(node.getAttribute("content")!=null || !hasNonTextChildNodes(node) || (datatypeValue!=null && datatypeValue.Length==0)){ string literal=node.getAttribute("content"); if(literal==null) { literal=getTextNodeText(node); } currentProperty=(!string.IsNullOrEmpty(localLanguage)) ? RDFTerm.fromLangString(literal, localLanguage) : RDFTerm.fromTypedString(literal); } else if(hasNonTextChildNodes(node) && (datatypeValue==null || datatypeValue.Equals(RDF_XMLLITERAL))){ // XML literal recurse=false; if(datatypeValue==null) { datatypeValue=RDF_XMLLITERAL; } try { string literal=ExclusiveCanonicalXML.canonicalize(node, false, namespacesLocal); currentProperty=RDFTerm.fromTypedString(literal,datatypeValue); } catch(ArgumentException){ // failure to canonicalize } } #if DEBUG if(!(newSubject!=null))throw new InvalidOperationException("doesn't satisfy newSubject!=null"); #endif outputGraph.Add(new RDFTriple( newSubject, RDFTerm.fromIRI(iri),currentProperty )); } } // Step 10 if(!skipElement && newSubject!=null){ foreach(var triple in context.incompleteTriples){ if(triple.direction==RDFa.ChainingDirection.Forward){ outputGraph.Add(new RDFTriple( context.parentSubject, triple.predicate, newSubject)); } else { outputGraph.Add(new RDFTriple( newSubject,triple.predicate, context.parentSubject)); } } } // Step 13 if(recurse){ foreach(var childNode in node.getChildNodes()){ IElement childElement; RDFa.EvalContext oldContext=context; if(childNode is IElement){ childElement=((IElement)childNode); //Console.WriteLine("skip=%s vocab=%s local=%s", // skipElement,context.defaultVocab, //localDefaultVocab); if(skipElement){ RDFa.EvalContext ec=oldContext.copy(); ec.language=localLanguage; ec.iriMap=iriMapLocal; ec.namespaces=namespacesLocal; context=ec; process(childElement,false); } else { RDFa.EvalContext ec=new RDFa.EvalContext(); ec.baseURI=oldContext.baseURI; ec.iriMap=iriMapLocal; ec.namespaces=namespacesLocal; ec.incompleteTriples=incompleteTriplesLocal; ec.parentSubject=((newSubject==null) ? oldContext.parentSubject : newSubject); ec.parentObject=((currentObject==null) ? ((newSubject==null) ? oldContext.parentSubject : newSubject) : currentObject); ec.language=localLanguage; context=ec; process(childElement,false); } } context=oldContext; } } }