Schema ("schema.xs"):
<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.whatever.com/schema">
<element name="fooOut">
<complexType name="fooOut">
<sequence>
<element name="bar">
<complexType>
<sequence>
<element name="attr1" type="sch:myBarType" minOccurs="0" maxOccurs="unbounded"/>
<element name="attr2" type="sch:myBarType" minOccurs="0" maxOccurs="unbounded"/>
</sequence>
</complexType>
</element>
<element name="stuff">
<complexType>
<sequence>
<element name="attr3" type="sch:myStuffType" minOccurs="0" maxOccurs="unbounded"/>
<element name="attr4" type="sch:myStuffType" minOccurs="0" maxOccurs="unbounded"/>
</sequence>
</complexType>
</element>
</sequence>
</complexType>
</element>
</schema>
Input:
<sch:foo xmlns:sch="http://www.whatever.com/schema">
<sch:attr1>val1</sch:attr1>
<sch:attr2>val2</sch:attr2>
<sch:attr3>val3</sch:attr3>
<sch:attr4>val4</sch:attr4>
</sch:foo>
Stylesheet:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:sch="http://www.whatever.com/schema">
<xsl:param name="schema-name" select="'schema.xs'"/>
<xsl:variable name="input" select="/"/>
<xsl:template match="/">
<xsl:apply-templates select="document($schema-name)/node()"/>
</xsl:template>
<xsl:template match="xs:element[xs:complexType]">
<xsl:element name="{@name}" namespace="http://www.whatever.com/schema">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
<xsl:template match="xs:element[not(xs:complexType)]">
<xsl:element name="{@name}" namespace="http://www.whatever.com/schema">
<xsl:value-of select="$input/*/sch:*[name()=current()/@name or
substring-after(name(),':')=current()/@name]"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
Result:
<?xml version="1.0" encoding="UTF-16"?>
<fooOut xmlns="http://www.whatever.com/schema">
<bar>
<attr1>val1</attr1>
<attr2>val2</attr2>
</bar>
<stuff>
<attr3>val3</attr3>
<attr4>val4</attr4>
</stuff>
</fooOut>
Note: This is an XSLT 1.0 solution, but I think this can be done better with XSLT 2.0.- Also, if the schema is a more proper one (elements definitions and types definitions) this method could work with keys. Another method (input driven and not schema driven), despite being more complex, also could be done but I'm runnig out of time.
Edit: Now, suppose these schemas
schemaA.xsd
<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.whatever.com/schema">
<include schemaLocation="schemaB.xsd"/>
<element name="fooOut" type="fooOut"/>
<complexType name="fooOut">
<element name="anotherGroup" type="anotherGroup" minOccurs="0" maxOccurs="unbounded"/>
</complexType>
<complexType name="anotherGroup">
<sequence>
<element name="name" type="xs:string" minOccurs="1" maxOccurs="1" />
<element name="bar" type="barListType" minOccurs="0" maxOccurs="1" />
<element name="stuff" type="stuffListType" minOccurs="0" maxOccurs="1" />
</sequence>
</complexType>
</schema>
schemaB.xsd
<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.whatever.com/schema">
<include schemaLocation="schemaC.xsd"/>
<complexType name="barListType">
<group ref="barGroup" maxOccurs="unbounded" />
</complexType>
<complexType name="stuffListType">
<group ref="stuffGroup" maxOccurs="unbounded" />
</complexType>
</schema>
schemaC.xsd
<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.whatever.com/schema">
<group name="barGroup">
<choice>
<element name="attr1" type="blah1" minOccurs="0" maxOccurs="1" />
<element name="attr2" type="blah2" minOccurs="0" maxOccurs="1" />
<!-- etc -->
</choice>
</group>
<group name ="stuffGroup">
<choice>
<element name="attr3" type="blah3" minOccurs="0" maxOccurs="1" />
<element name="attr4" type="blah4" minOccurs="0" maxOccurs="1" />
<!-- etc -->
</choice>
</group>
</schema>
This stylesheet:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:output method="xml" encoding="UTF-8" />
<xsl:param name="schema-name" select="'schemaA.xsd'" />
<xsl:variable name="input" select="/*/*/*" />
<xsl:variable name="root" select="document($schema-name)/*/xs:element[not(..//xs:element/@ref = @name)]" />
<xsl:variable name="uri" select="$root/../@targetNamespace" />
<xsl:template match="/" name="root">
<xsl:param name="schema" select="$root/../*"/>
<xsl:choose>
<xsl:when test="$schema[self::xs:include]">
<xsl:call-template name="root">
<xsl:with-param name="schema" select="$schema[not(self::xs:include)]|document($schema[self::xs:include]/@schemaLocation)/*/*"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="$root">
<xsl:with-param name="schema" select="$schema"/>
<xsl:with-param name="input" select="$input"/>
</xsl:apply-templates>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="xs:element">
<xsl:param name="schema"/>
<xsl:param name="input"/>
<xsl:variable name="complex" select="xs:complexType|
$schema[self::xs:complexType][@name=current()/@type]"/>
<xsl:element name="{@name|@ref}" namespace="{$uri}">
<xsl:choose>
<xsl:when test="$complex">
<xsl:apply-templates select="$complex">
<xsl:with-param name="schema" select="$schema"/>
<xsl:with-param name="input" select="$input"/>
</xsl:apply-templates>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$input[local-name()=current()/@name and
namespace-uri()=$uri]"/>
</xsl:otherwise>
</xsl:choose>
</xsl:element>
</xsl:template>
<xsl:template match="xs:group[@ref]">
<xsl:param name="schema"/>
<xsl:param name="input"/>
<xsl:apply-templates select="$schema[self::xs:group][@name=current()/@ref]">
<xsl:with-param name="schema" select="$schema"/>
<xsl:with-param name="input" select="$input"/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="xs:element[@name='name']" priority="1">
<xsl:element name="{@name}" namespace="{$uri}">foobar</xsl:element>
</xsl:template>
<xsl:template match="xs:element[@maxOccurs='unbounded']">
<xsl:param name="schema"/>
<xsl:param name="input"/>
<xsl:variable name="current" select="."/>
<xsl:for-each select="$input">
<xsl:element name="{$current/@name}" namespace="{$uri}">
<xsl:apply-templates select="$schema[self::xs:complexType][@name=$current/@type]">
<xsl:with-param name="schema" select="$schema"/>
<xsl:with-param name="input" select="./*"/>
</xsl:apply-templates>
</xsl:element>
</xsl:for-each>
</xsl:template>
<xsl:template match="*">
<xsl:param name="schema"/>
<xsl:param name="input"/>
<xsl:apply-templates>
<xsl:with-param name="schema" select="$schema"/>
<xsl:with-param name="input" select="$input"/>
</xsl:apply-templates>
</xsl:template>
</xsl:stylesheet>
Result:
<fooOut xmlns="http://www.whatever.com/schema">
<anotherGroup>
<name>foobar</name>
<bar>
<attr1>val1</attr1>
<attr2>val2</attr2>
</bar>
<stuff>
<attr3>val3</attr3>
<attr4>val4</attr4>
</stuff>
</anotherGroup>
<anotherGroup>
<name>foobar</name>
<bar>
<attr1>val5</attr1>
<attr2>val6</attr2>
</bar>
<stuff>
<attr3>val7</attr3>
<attr4>val8</attr4>
</stuff>
</anotherGroup>
</fooOut>
Note: This works but your second questions (or problem) shows that there is no general case stylesheet. Why? Because with XSLT you must bind an input (with well known schema) to an output (with well known schema too). So this specific stylesheet could do the job:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:sch="http://www.whatever.com/schema">
<xsl:output method="xml" encoding="UTF-8" />
<xsl:param name="schema-name" select="'schemaC.xsd'" />
<xsl:template match="sch:foo">
<sch:fooOut>
<xsl:apply-templates/>
</sch:fooOut>
</xsl:template>
<xsl:template match="sch:myGroup">
<sch:anotherGroup>
<sch:name>foobar</sch:name>
<sch:bar>
<xsl:copy-of select="*[local-name()=document($schema-name)/*/*[@name='barGroup']//@name]" />
</sch:bar>
<sch:stuff>
<xsl:copy-of select="*[local-name()=document($schema-name)/*/*[@name='stuffGroup']//@name]" />
</sch:stuff>
</sch:anotherGroup>
</xsl:template>
</xsl:stylesheet>
Result:
<sch:fooOut xmlns:sch="http://www.whatever.com/schema">
<sch:anotherGroup>
<sch:name>foobar</sch:name>
<sch:bar>
<sch:attr1>val1</sch:attr1>
<sch:attr2>val2</sch:attr2>
</sch:bar>
<sch:stuff>
<sch:attr3>val3</sch:attr3>
<sch:attr4>val4</sch:attr4>
</sch:stuff>
</sch:anotherGroup>
<sch:anotherGroup>
<sch:name>foobar</sch:name>
<sch:bar>
<sch:attr1>val5</sch:attr1>
<sch:attr2>val6</sch:attr2>
</sch:bar>
<sch:stuff>
<sch:attr3>val7</sch:attr3>
<sch:attr4>val8</sch:attr4>
</sch:stuff>
</sch:anotherGroup>
</sch:fooOut>