Timed Text Markup Language(TTML)ドキュメントの非常に単純な変換を実行しようとしています。TTMLファイルの最小限の例を次に示します。
<?xml version="1.0" encoding="UTF-8"?>
<tt xml:lang="en" xmlns="http://www.w3.org/2006/04/ttaf1"
xmlns:tts="http://www.w3.org/2006/04/ttaf1#styling">
<head>
</head>
<body>
<div xml:lang="en" style="1">
<p begin="00:00:00.20" dur="00:00:02.26">>> One time entry<br/>with a line break.</p>
</div>
</body>
</tt>
ドキュメントのデフォルトの名前空間に注意してください。それが私が抱えている問題の鍵です。
これが私が使用している変換です。これがすべてです、それは非常に簡単です。
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
xmlns:tt="http://www.w3.org/2006/04/ttaf1">
<xsl:output method="text" indent="yes" />
<xsl:strip-space elements="*" />
<xsl:preserve-space elements="tt:p"/>
<!-- The indentation of the close tag for the following node is crucial to the transformed layout. Don't move it! -->
<xsl:template match="tt:p"><xsl:apply-templates /> 
</xsl:template>
<xsl:template match="tt:p/text()"><xsl:copy /> </xsl:template>
</xsl:stylesheet>
私たちのデータセットには何百ものドキュメントがあり、それらすべてに同じデフォルトの名前空間があるわけではありません。ただし、上記のXSLTからわかるように、変換は単純であり、コアデータ要素に基づいている<p />
ため、最終的に名前空間のバリエーションは重要ではありません。
XSLTファイルには明示的に定義された名前空間プレフィックス()があるため、上記のXSLは現在一部のソースファイルで機能しますtt
。ただし、これは、デフォルトの名前空間が異なる別のソースファイルに遭遇した場合は機能しません。
したがって、既知のプレフィックスに対して任意の未知の名前空間値をXSLTに提供する方法を見つける必要があります。ソースドキュメントのデフォルトの名前空間を見つけるために使用できるコードがあります。
XPathDocument sourceDoc = new XPathDocument("sourcefile.xml");
XPathNavigator sourceNav = sourceDoc.CreateNavigator();
sourceNav.MoveToFollowing(XPathNodeType.Element);
var sourceNS = sourceNav.GetNamespacesInScope(XmlNamespaceScope.ExcludeXml);
string defNS = sourceNS.Single(n => n.Key =="").Value;
これは正しく私に与えますhttp://www.w3.org/2006/04/ttaf1
。しかし、私はこの値をどうするか理解できないようです。XslCompiledTransform
私は何時間もの間、インスタンスに変数の名前空間を提供しようとして検索し、実験してきました。トランスフォーム自体の領域内には、それを取得できるものは何もないようです。
XmlDocument
名前テーブルを操作するために、XSLTファイルをに明示的にロードしようとしました(xmlns:tt="..."
上記のXSLTで明示的な名前空間宣言を削除した後)。
XslCompiledTransform objXsl = new XslCompiledTransform();
StringWriter writer = new StringWriter();
XPathDocument sourceDoc;
XmlDocument xslDoc = new XmlDocument();
XPathNavigator sourceNav, xslNav;
XmlNamespaceManager xslNsManager;
sourceDoc = new XPathDocument("sourcefile.xml");
sourceNav = sourceDoc.CreateNavigator();
sourceNav.MoveToFollowing(XPathNodeType.Element);
var sourceNS = sourceNav.GetNamespacesInScope(XmlNamespaceScope.ExcludeXml);
xslDoc.Load("transform.xslt");
xslNsManager = new XmlNamespaceManager(xslDoc.NameTable);
xslNsManager.AddNamespace("tt", sourceNS.Single(n => n.Key =="").Value);
xslNav = xslDoc.CreateNavigator();
objXsl.Load(xslNav);
objXsl.Transform(sourceNav, null, writer);
これは実際の変換まで実行され、そこで私は次のようにXslLoadException
述べますPrefix 'tt' is not defined.
私はこの時点で途方に暮れています。検索から見つけることができるすべてのことは、名前空間をXSLTドキュメントに入れることについて説明しています(私はすでに持っていて、1つの名前空間値に対して正常に機能します)。名前空間の定義をその場でトランスフォームに追加する方法を説明しているMSDNドキュメントやその他の場所には何も見つかりません。
誰かアイデアはありますか?