XslCompiledTransform и пользовательский XmlUrlResolver :«Запись с таким ключом уже существует»

Есть ли способ отлаживать документы XSLT, которые загружаются из базы данных с помощью пользовательского XmlUrlResolver, или кто-нибудь знает, о чем сообщение об ошибке ниже?

У меня есть таблица стилей XSLT, которая импортирует общий документ xslt :


. Схема обрабатывается пользовательскимXmlResolverкоторый загружает документ XSLT из БД, но я получаю сообщение об ошибке:

An entry with the same key already exists.

Общий документ XSLT, на который ссылается xsl:import, содержит несколько общих шаблонов XSLT, каждый из которых имеет уникальное имя.

Эта ошибка начала возникать после перемещения XSLT-документов из локальной файловой системы в базу данных. При использовании схем импорта по умолчанию, указывающих на локальные файлы, и при загрузке документов XSLT из локальной файловой системы ошибка не возникает.

Я также пытался включить отладку при создании экземпляра XslCompiledTransform, но почему-то невозможно «зайти» в базу данных -на основе XSLT.

_xslHtmlOutput = new XslCompiledTransform(XSLT_DEBUG);

Обновление:Ниже приведен в основном код преобразователя, как запрошено, но исключение не происходит внутри моего кода; таким образом, я не думаю, что в приведенном ниже коде нет очевидной причины. (Этот же код фактически используется для загрузки таблиц стилей XSLT, содержащих импорт, и при комментировании импорта все работает как положено.)

public class XmlDBResolver : XmlUrlResolver
{
    private IDictionary GetUriComponents(String uri)
    {
        bool useXmlPre = false;
        uri = uri.Replace("db://", "");
        useXmlPre = uri.StartsWith("xml/");
        uri = uri.Replace("xml/", "");
        IDictionary dict = new Dictionary();
        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://.hist.org
         *  db://..hist.org
         *  db://...hist.org
         * 
         * */

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

        XmlReader reader = null;

        switch (absoluteUri.Scheme)
        {
            case "db":
                string origString = absoluteUri.OriginalString;
                IDictionary 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);
}

Обновление:Я попытался изолировать проблему, временно загрузив таблицы стилей с веб-сервера, и это работает. Я узнал, что SQL Server, по-видимому, хранит только фрагменты XML без объявления XML, в отличие от таблиц стилей, хранящихся на веб-сервере.

Обновление:Трассировка стека исключения:

System.Xml.Xsl.XslLoadException: XSLT-Kompilierungsfehler. Fehler bei (9,1616). ---> System.ArgumentException: An entry with the same key already exists.. bei System.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 reader) bei System.Xml.Xsl.Xslt.XsltLoader.Load(Compiler compiler, Object stylesheet, XmlResolver xmlResolver) bei System.Xml.Xsl.Xslt.Compiler.Compile(Object stylesheet, XmlResolver xmlResolver, QilExpression& qil) bei System.Xml.Xsl.XslCompiledTransform.LoadInternal(Object stylesheet, XsltSettings settings, XmlResolver stylesheetResolver) bei System.Xml.Xsl.XslCompiledTransform.Load(String stylesheetUri, XsltSettings settings, XmlResolver stylesheetResolver) bei (my namespace and class).GetXslTransform(Boolean preTransform) bei (my namespace and class).get_XslHtmlOutput() bei (my namespace and class).get_DisplayMarkup()

5
задан Ole Viaud-Murat 17 August 2012 в 12:56
поделиться