I'm copying components between versions of essentially the same schema, of which the latter has a stricter XSLT attached to it's RTF field.

The code (TOM.Net):

    value = ((TextField)oldField).Value;

    var def = (XhtmlFieldDefinition)field.Definition;
    var tfm = new XslCompiledTransform();
    tfm.Load(def.FilterXslt);
    
    var settings = new XmlReaderSettings();
    settings.ConformanceLevel = ConformanceLevel.Fragment;
    
    using (var sw = new StringWriter())
    {
        using (var sr = new StringReader(value))
        {
            using (var reader = XmlReader.Create(sr, settings))
            {
                tfm.Transform(reader, null, sw);
                field.Value = sw.ToString();
            }
        }
    }

The problems i'm getting:

 1. If it runs "as is", all XML is stripped off. That's likely because input **value** has *xmlns="http://www.w3.org/1999/xhtml"* declaration on *some* (not *all*, by the way) of it's HTML tags, but in XSLT these tags are not bound to anything but default *xmlns="http://www.w3.org/1999/XSL/Transform"*.

 2. If i do an unfair move by exterminating "xmlns" in content, say, like this: **new StringReader(value.Replace(@" xmlns=""http://www.w3.org/1999/xhtml""", string.Empty))**, then transform works fine, but upon calling **component.Save()**, it says something like this:

> XML validation error. Reason: The element 'text' in namespace 'http://www.unilever.com/general' has invalid child element 'h2'. List of possible elements expected: any element in namespace 'http://www.w3.org/1999/xhtml'..

As i understand, the proper way of tackling my problem would be to alter XSLT in such a way as to: 1. Declare XHTML namespace, 2. Modify XPath expressions to use FQ names.

Unfortunately, modifying field's XSLT is not an option.

Also, ILSpy cannot find any references of XhtmlFieldDefinition.FilterXslt to get an idea how Tridion itself does it.

How to transform XHtmlField value according to attached filter XSLT?

**EDIT**
LinqPad snipped that demonstrates the transformation (but not the behavior during *Save*!): https://gist.github.com/esteewhy/6248993

**EDIT (Solution)**
Got it working using **user978511** idea/hack of re-applying XHTML namespace to top-most elements. Still would be curious how Tridion does it internally. Nevertheless, solutions looks like this:

    // remove XHTML NS which confused XSLT
    var input = value.Replace(@"xmlns=""http://www.w3.org/1999/xhtml""", string.Empty);
    
    // apply XSLT as shown above

    // put back XHTML NS on top-most elements
    field.Value = AssignTopLevelNS(sb.ToString());

    // .. and the essential method itself
    static string AssignTopLevelNS(string xmlFragment)
    {
        var k = new XmlDocument();
        k.LoadXml("<xml>" + xmlFragment + "</xml>");
        var xKey = k.CreateAttribute("xmlns");
        xKey.Value = "http://www.w3.org/1999/xhtml";
        
        k.DocumentElement.ChildNodes.Cast<XmlNode>().ToList().ForEach(element => {
            element.Attributes.SetNamedItem(xKey);
        });
        
        return k.DocumentElement.InnerXml;
    }