私が思いついた最高のものは、デフォルトのxmlns属性を持つ要素に異なる名前空間プレフィックスを与えるスタイルシートでした。私のドキュメントには複数のxmlns="..."属性があるため、これはツリーの下で再帰的に適用されます。
それが他の誰かに役立つ場合のために、ここにあります...私のXSLスキルは主にグーグルに基づいていますが:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
xmlns:ms="urn:schemas-microsoft-com:xslt"
>
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:variable name="root_default_ns" select="namespace-uri(/*)" />
<xsl:template match="node()|text()">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates select="node() | text()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*">
<xsl:param name="old_default_ns" select="$root_default_ns"/>
<xsl:param name="new_default_ns" />
<!-- match any element in the source default namespace -->
<xsl:if test="namespace-uri() = $old_default_ns">
<xsl:element name="ns_{$new_default_ns}:{local-name()}" namespace="{$old_default_ns}">
<xsl:copy-of select="@*"/>
<xsl:apply-templates select="node() | text()">
<xsl:with-param name="old_default_ns" select="$old_default_ns" />
<xsl:with-param name="new_default_ns" select="$new_default_ns" />
</xsl:apply-templates>
</xsl:element>
</xsl:if>
<!-- match any element with a prefix qualified namespace -->
<xsl:if test="namespace-uri() != $old_default_ns and contains(name(), ':')">
<xsl:element name="{name()}" namespace="{namespace-uri()}">
<xsl:copy-of select="@*"/>
<xsl:apply-templates select="node() | text()">
<xsl:with-param name="old_default_ns" select="$old_default_ns" />
<xsl:with-param name="new_default_ns" select="$new_default_ns" />
</xsl:apply-templates>
</xsl:element>
</xsl:if>
<!-- match any element *without* a prefix qualified namespace -->
<xsl:if test="namespace-uri() != $old_default_ns and contains(name(), ':') = false">
<xsl:variable name="new_ns" select="count(ancestor::*)" />
<xsl:element name="ns_{$new_ns}:{name()}" namespace="{namespace-uri()}" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" >
<xsl:copy-of select="@*"/>
<xsl:apply-templates select="node() | text()">
<xsl:with-param name="old_default_ns" select="namespace-uri()" />
<xsl:with-param name="new_default_ns"><xsl:value-of select="$new_ns" /></xsl:with-param>
</xsl:apply-templates>
</xsl:element>
</xsl:if>
</xsl:template>
<!-- match root element only, and inject Silverlight namespace -->
<xsl:template match="/*">
<xsl:element name="ns_root:{local-name()}" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" namespace="{$root_default_ns}">
<!-- inject the Silverligth ns -->
<xsl:variable name="dummy">
<Dummy/>
</xsl:variable>
<xsl:copy-of select="ms:node-set($dummy)/*/namespace::*"/>
<xsl:copy-of select="@*"/>
<xsl:apply-templates select="node() | text()">
<xsl:with-param name="old_default_ns" select="$root_default_ns" />
<xsl:with-param name="new_default_ns">root</xsl:with-param>
</xsl:apply-templates>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
残念ながら、このフープをジャンプした後、XamlReaderが期待する規則に準拠するXAML文字列を取得しますが、代わりにSystem.ExecutionEngineExceptionを生成します(WPF XamlReaderは引き続き文字列を正常に処理します)