5

カスタムXmlUrlResolverによってデータベースからロードされたXSLTドキュメントをデバッグする方法はありますか、または誰かが知っていますか、以下のエラーメッセージは何についてですか?

一般的なxsltドキュメントをインポートするXSLTスタイルシートがあります。

<xsl:import href="db://common.hist.org"/>

スキームはXmlResolver、DBからXSLTドキュメントをロードするカスタムによって処理されますが、エラーが発生します。

同じキーのエントリがすでに存在します。

によって参照される一般的なXSLTドキュメントにxsl:importは、それぞれが一意の名前を持ついくつかの一般的なXSLTテンプレートが含まれています。

このエラーは、XSLTドキュメントをローカルファイルシステムからデータベースに移動した後に発生し始めました。ローカルファイルを指すデフォルトのインポートスキームを使用している場合、およびローカルファイルシステムからXSLTドキュメントをロードする場合、エラーは発生しません。

また、のインスタンスを作成するときにデバッグをオンにしようとしましたXslCompiledTransformが、どういうわけか、データベースベースのXSLTに「ステップイン」することはできません。

_xslHtmlOutput = new XslCompiledTransform(XSLT_DEBUG);

更新:以下は基本的に要求されたリゾルバーコードですが、私のコード内で例外は発生していません。したがって、以下のこのコードには明らかな理由はないと思います。(これと同じコードは、インポートを含むXSLTスタイルシートをロードするために実際に使用され、インポートをコメントアウトすると、すべてが期待どおりに機能します。)

public class XmlDBResolver : XmlUrlResolver
{
    private IDictionary<string,string> GetUriComponents(String uri)
    {
        bool useXmlPre = false;
        uri = uri.Replace("db://", "");
        useXmlPre = uri.StartsWith("xml/");
        uri = uri.Replace("xml/", "");
        IDictionary<string, string> dict = new Dictionary<string, string>();
        string app = null, area = null, subArea = null;

        if (!String.IsNullOrWhiteSpace(uri))
        {
            string[] components = uri.Split('.');

            if (components == null)
                throw new Exception("Invalid Xslt URI");

            switch (components.Count())
            {
                case 3:
                    app = components[0];
                    break;
                case 4:
                    area = components[0];
                    app = components[1];
                    break;
                case 5:
                    subArea = components[0];
                    area = components[1];
                    app = components[2];
                    break;
                default:
                    throw new Exception("Invalid Xslt URI");
            }

            dict.Add("application", app);
            dict.Add("area", area);
            dict.Add("subArea", subArea);
            dict.Add("xmlPreTransform", String.Format("{0}", useXmlPre));
        }

        return dict;
    }

    public override System.Net.ICredentials Credentials
    {
        set { /* TODO: check if we need credentials */ }
    }

    public override object GetEntity(Uri absoluteUri, string role, Type ofObjectToReturn)
    {
        /*
         *  db://<app>.hist.org
         *  db://<area>.<app>.hist.org
         *  db://<subArea>.<area>.<app>.hist.org
         * 
         * */

        Tracing.TraceHelper.WriteLine(String.Format("GetEntity {0}", absoluteUri));

        XmlReader reader = null;

        switch (absoluteUri.Scheme)
        {
            case "db":
                string origString = absoluteUri.OriginalString;
                IDictionary<string, string> xsltDict = GetUriComponents(origString);

                if(String.IsNullOrWhiteSpace(xsltDict["area"]))
                {
                    reader = DatabaseServiceFactory.DatabaseService.GetApplicationXslt(xsltDict["application"]);
                }
                else if (!String.IsNullOrWhiteSpace(xsltDict["area"]) && String.IsNullOrWhiteSpace(xsltDict["subArea"]) && !Boolean.Parse(xsltDict["xmlPreTransform"]))
                {
                    reader = DatabaseServiceFactory.DatabaseService.GetAreaXslt(xsltDict["application"], xsltDict["area"]);
                }
                else if (!String.IsNullOrWhiteSpace(xsltDict["area"]) && !String.IsNullOrWhiteSpace(xsltDict["subArea"]))
                {
                    if(Boolean.Parse(xsltDict["xmlPreTransform"]))
                        reader = DatabaseServiceFactory.DatabaseService.GetSubareaXmlPreTransformXslt(xsltDict["application"], xsltDict["area"], xsltDict["subArea"]);
                    else
                        reader = DatabaseServiceFactory.DatabaseService.GetSubareaXslt(xsltDict["application"], xsltDict["area"], xsltDict["subArea"]);
                }
                return reader;

            default:
                return base.GetEntity(absoluteUri, role, ofObjectToReturn);
        }
    }

完全を期すために、IDatabaseServiceインターフェース(関連部分):

public interface IDatabaseService
{
    ...
    XmlReader GetApplicationXslt(String applicationName);
    XmlReader GetAreaXslt(String applicationName, String areaName);
    XmlReader GetSubareaXslt(String applicationName, String areaName, String subAreaName);
    XmlReader GetSubareaXmlPreTransformXslt(String applicationName, String areaName, String subAreaName);
}

更新:代わりにWebサーバーからスタイルシートを一時的にロードすることで問題を特定しようとしましたが、これは機能します。Webサーバーに保存されているスタイルシートとは対照的に、SQLServerはXML宣言なしでXMLフラグメントのみを保存しているように見えることを学びました。

更新:例外のスタックトレース:

System.Xml.Xsl.XslLoadException:XSLT-Kompilierungsfehler。フェラーベイ(9,1616)。---> System.ArgumentException:同じキーのエントリがすでに存在します。beiSystem.Collections.Specialized.ListDictionary.Add(Object key、Object value)bei System.Collections.Specialized.HybridDictionary.Add(Object key、Object value)bei System.Xml.Xsl.Xslt.XsltLoader.LoadStylesheet(XmlReader reader、Boolean include)bei System.Xml.Xsl.Xslt.XsltLoader.LoadStylesheet(Uri uri、Boolean include)bei System.Xml.Xsl.Xslt.XsltLoader .LoadStylesheet(XmlReader reader、Boolean include)--- Ende der inneren Ablaufverfolgung des Ausnahmestacks --- bei System.Xml.Xsl.Xslt.XsltLoader.LoadStylesheet(XmlReader reader、Boolean include)bei System.Xml.Xsl.Xslt.XsltLoader .Load(XmlReaderリーダー)bei System.Xml.Xsl.Xslt.XsltLoader.Load(コンパイラーコンパイラー、オブジェクトスタイルシート、

4

1 に答える 1

10
于 2012-08-17T13:49:06.893 に答える