(: TODO: - documentation for this - paths have to encompass qualified names :) declare namespace its ="http://www.w3.org/2005/11/its"; declare namespace eg ="http://example.com#"; declare namespace saxon="http://saxon.sf.net/"; declare option saxon:output "method=text"; let $getDocumentRulesNamespaces := for $namespaceUri in ( for $namespaces in ./descendant-or-self::its:ns return string($namespaces/@its:uri) ) return (concat( " declare namespace ", (let $prefix := ./descendant-or-self::its:ns[@its:uri=$namespaceUri][1]/@its:prefix return string($prefix)), "='", $namespaceUri, "';" )) let $declareNamespaces := (" declare namespace eg ='http://example.com#'; declare namespace its ='http://www.w3.org/2005/11/its';", $getDocumentRulesNamespaces," ") let $functionWritePath := " declare function eg:writePath($node as item()*,$path as xs:string) as xs:string { if ($node[self::element() or self::attribute()]) then (let $position := count($node/preceding-sibling::*[name() = name($node)]) +1 let $newpath := if ($node[self::element()]) then( concat(name($node), '[', $position,']/', $path)) else( concat($path, '@', name($node), '/')) return eg:writePath($node/parent::*,$newpath)) else substring((concat('/',$path)),0,string-length($path)+1) }; " (: $translateTestNodeAutonomous, created as described in 1) above :) let $inputDoc := document-uri(.) (: ------------------------------- Definitions for translatability ------------------------------- :) let $translateTestNodeAutonomous := let $query := let $string1 := concat(" if ($nodes[1] intersect doc('", $inputDoc, "')") let $string2 := concat(") then ("," ") let $string3 := ", attribute eg:translateSelector { eg:writePath($nodes[1],'')} ) else" for $documentRule in ./descendant-or-self::its:translateRule let $node := $documentRule/@its:selector let $translateType := (concat("attribute eg:translateValue {'", if($documentRule/@its:translate="yes") then ("yes (autonomous)") else ("no (autonomous)"), "'}")) return concat($string1, $node, $string2, $translateType, $string3) return $query let $translateTestNodeContigent := (" if($nodes[1]/@its:translate) then ( attribute eg:translateValue { concat ($nodes[1]/@its:translate, ' (contigent)') }, attribute eg:translateSelector {eg:writePath($nodes[1],'')} ) else if($nodes[1]/ancestor::*[@its:translate] and $nodes[1]/self::element()) then ( attribute eg:translateValue { concat( $nodes[1]/ancestor::*[@its:translate][1]/@its:translate,' (inherited)') }, attribute eg:translateSelector {eg:writePath($nodes[1],'')} ) else ") let $translateDefaultRuleAttributes := concat(" if ($nodes[1] intersect doc('",$inputDoc,"')//@*) then (attribute eg:translateValue {'no (default)'}, attribute eg:translateSelector { eg:writePath($nodes[1],'')} )") let $TranslateDefaultRuleElements := concat(" else if ($nodes[1] intersect doc('",$inputDoc, "')/descendant-or-self::*) then (attribute eg:translateValue {'yes (default)'}, attribute eg:translateSelector { eg:writePath($nodes[1],'')} )") let $functionTestNodeTranslateBegin := (" declare function eg:testNodeTranslate($nodes as item()*) as item()* { if(empty($nodes)) then() else ( element eg:node { ") let $functionTestNodeTranslateEnd := "else() } , eg:testNodeTranslate($nodes[position()>1])) }; " let $functionTestNodeTranslateAll := ($functionTestNodeTranslateBegin, $translateTestNodeContigent, $translateTestNodeAutonomous, $translateDefaultRuleAttributes, $TranslateDefaultRuleElements, $functionTestNodeTranslateEnd) (: ------------------------------- Definitions for directionality ------------------------------- :) let $dirTestNodeAutonomous := let $query := let $string1 := concat(" if ($nodes[1] intersect doc('", $inputDoc, "')") let $string2 := concat(") then ("," ") let $string3 := ", attribute eg:dirSelector { eg:writePath($nodes[1],'')} ) else" for $documentRule in ./descendant-or-self::its:dirRule let $node := $documentRule/@its:selector let $dirType := (concat("attribute eg:dirValue {'", $documentRule/@its:dir, " (autonomous)'}")) return concat($string1, $node, $string2, $dirType, $string3) return $query let $dirTestNodeContigent := (" if($nodes[1]/@its:dir) then ( attribute eg:dirValue { concat ($nodes[1]/@its:dir, ' (contigent)') }, attribute eg:dirSelector {eg:writePath($nodes[1],'')} ) else if($nodes[1]/ancestor::*[@its:dir]) then ( attribute eg:dirValue { concat( $nodes[1]/ancestor::*[@its:dir][1]/@its:dir, ' (inherited)' )}, attribute eg:dirSelector {eg:writePath($nodes[1],'')} ) else ") let $dirDefaultRuleAttributes := concat(" if ($nodes[1] intersect doc('",$inputDoc,"')//@*) then (attribute eg:dirValue {'ltr (default)'}, attribute eg:dirSelector { eg:writePath($nodes[1],'')} )") let $DirDefaultRuleElements := concat(" else if ($nodes[1] intersect doc('",$inputDoc, "')/descendant-or-self::*) then (attribute eg:dirValue {'ltr (default)'}, attribute eg:dirSelector { eg:writePath($nodes[1],'')} )") let $functionTestNodeDirBegin := (" declare function eg:testNodeDir($nodes as item()*) as item()* { if(empty($nodes)) then() else ( element eg:node { ") let $functionTestNodeDirEnd := "else() } , eg:testNodeDir($nodes[position()>1])) }; " let $functionTestNodeDirAll := ($functionTestNodeDirBegin, $dirTestNodeContigent, $dirTestNodeAutonomous, $dirDefaultRuleAttributes, $DirDefaultRuleElements, $functionTestNodeDirEnd) (: ------------------------------- Main program -------------------------------:) (: the input document is in $inputDoc :) let $processInput := concat("let$inputDoc := (doc('", $inputDoc, "')//*[not(namespace-uri()='http://www.w3.org/2005/11/its')] | doc('", $inputDoc, "')//@*[not(namespace-uri()='http://www.w3.org/2005/11/its') and not(namespace-uri()='http://www.w3.org/XML/1998/namespace')]) return element eg:selections { element eg:TranslateSelections { eg:testNodeTranslate($inputDoc) }, element eg:dirSelections { eg:testNodeDir($inputDoc) } } ") return ( $declareNamespaces, $functionWritePath, $functionTestNodeTranslateAll, $functionTestNodeDirAll, $processInput )