Nano Hash - криптовалюты, майнинг, программирование

C# — возможно ли (и как) выполнять преобразования XSL с помощью SgmlReader

Мне нужно было преобразовать содержимое HTML веб-страницы с помощью XSLT . Поэтому я использовал SgmlReader и написал приведенный ниже фрагмент кода (в конце концов я подумал, что это XmlReader тоже...)

XmlReader xslr = XmlReader.Create(new StringReader(
    "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
    "<xsl:stylesheet xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" version=\"1.0\">" +
    "<xsl:output method=\"xml\" encoding=\"UTF-8\" version=\"1.0\" />" +
    "<xsl:template match=\"/\">" +
    "<XXX xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"><xsl:value-of select=\"count(//br)\" /></XXX>" +
    "</xsl:template>" +
    "</xsl:stylesheet>"));

XslCompiledTransform xslt = new XslCompiledTransform();
xslt.Load(xslr);

using (SgmlReader html = new SgmlReader())
{
    StringBuilder sb = new StringBuilder();
    using (TextWriter sw = new StringWriter(sb))
    using (XmlWriter xw = new XmlTextWriter(sw))
    {
        html.InputStream = new StringReader(Resources.html_orig);
        html.DocType = "HTML";

        try
        {
            xslt.Transform(html, xw);
            string output = sb.ToString();
            System.Console.WriteLine(output);
        }
        catch (Exception exc)
        {
            System.Console.WriteLine("{0} : {1}", exc.GetType().Name, exc.Message);
            System.Console.WriteLine(exc.StackTrace);
        }
    }
}

Тем не менее, я получаю это сообщение об ошибке

NullReferenceException : Object reference not set to an instance of an object.
   at MS.Internal.Xml.Cache.XPathDocumentBuilder.Initialize(XPathDocument doc, IXmlLineInfo lineInfo, String baseUri, LoadFlags flags)
   at MS.Internal.Xml.Cache.XPathDocumentBuilder..ctor(XPathDocument doc, IXmlLineInfo lineInfo, String baseUri, LoadFlags flags)
   at System.Xml.XPath.XPathDocument.LoadFromReader(XmlReader reader, XmlSpace space)
   at System.Xml.XPath.XPathDocument..ctor(XmlReader reader, XmlSpace space)
   at System.Xml.Xsl.Runtime.XmlQueryContext.ConstructDocument(Object dataSource, String uriRelative, Uri uriResolved)
   at System.Xml.Xsl.Runtime.XmlQueryContext..ctor(XmlQueryRuntime runtime, Object defaultDataSource, XmlResolver dataSources, XsltArgumentList argList, WhitespaceRuleLookup wsRules)
   at System.Xml.Xsl.Runtime.XmlQueryRuntime..ctor(XmlQueryStaticData data, Object defaultDataSource, XmlResolver dataSources, XsltArgumentList argList, XmlSequenceWriter seqWrt)
   at System.Xml.Xsl.XmlILCommand.Execute(Object defaultDocument, XmlResolver dataSources, XsltArgumentList argumentList, XmlSequenceWriter results)
   at System.Xml.Xsl.XmlILCommand.Execute(Object defaultDocument, XmlResolver dataSources, XsltArgumentList argumentList, XmlWriter writer, Boolean closeWriter)
   at System.Xml.Xsl.XmlILCommand.Execute(XmlReader contextDocument, XmlResolver dataSources, XsltArgumentList argumentList, XmlWriter results)
   at System.Xml.Xsl.XslCompiledTransform.Transform(XmlReader input, XmlWriter results)

Я нашел способ обойти это, преобразовав HTML в XML и затем применив преобразование, но это неэффективное решение, потому что:

  1. Промежуточный вывод XHTML помещается в буфер , поэтому требуется дополнительная память.
  2. Процесс преобразования требует дополнительной обработки CPU, и одна и та же иерархия проходится дважды (теоретически без необходимости).

Итак (поскольку я знаю, что сообщество StackOverflow всегда дает отличные ответы, в то время как другие форумы C# меня полностью разочаровали ;o), я буду ждать отзывов. и предложения по выполнению преобразований XSL с использованием HTML напрямую (даже если SgmlReader нужно заменить другой похожей библиотекой).

30.11.2010

  • О подчеркнутом вопросе: XSLT 1.0 работает с деревом ввода XML (XSLT 2.0 может использовать неанализируемые ресурсы). Если у вас есть что-то, что не является XML-деревом, вам нужно использовать какой-то метод для сопоставления этого с XML-деревом. 30.11.2010
  • Олемис, просто примечание: XslCompiledTransform - это процессор XSLT 1.0, поэтому, если вы используете версию = 2.0 в своей таблице стилей, она работает в режиме прямой совместимости, и вы не получите сообщения обо всех синтаксических ошибках XSLT 1.0. Поэтому я бы начал устанавливать версию = 1.0 в вашей таблице стилей, поскольку тогда XslCompiledTransform уже сообщит вам при вызове Load о том, что ваша таблица стилей синтаксически неверна, поскольку xsl: output внутри xsl: template не разрешен. Поможет ли это решить вашу проблему при загрузке SgmlReader, я не уверен, вам нужно будет предоставить образец HTML, который вы используете, который дает исключение. 30.11.2010

Ответы:


1

Даже если класс SgmlReader расширяет класс XmlReader, это не означает, что он также ведет себя как XmlReader.

Технически также не имеет смысла, что SgmlReader является подклассом XmlReader, просто потому, что SGML является надмножеством XML, а не подмножеством.

Вы не написали о цели своего преобразования, а в целом HTML Agility Pack — хороший вариант для работы с HTML.

30.11.2010
  • При всем уважении это действительно имеет смысл (по крайней мере, с точки зрения ООП) из-за того, что XmlReader — это тип, все, что реализует этот интерфейс можно манипулировать (в данном случае читать) как если бы это был документ XML. Действительно, имеет смысл реализовать XmlReader для других структурированных форматов, таких как файлы YAML , INI, ... даже если они вообще не являются разметкой. , это структурированные документы, которые вы, возможно, захотите прочитать и преобразовать в структурированном виде. Просто мое мнение. 02.12.2010
  • @Olemis Lang: На мой взгляд, это не имеет смысла, потому что XmlReader ожидает правильно сформированный документ, то есть документ с древовидной структурой. SGML этого не предусматривает, поэтому такие методы, как ReadSubtree или ReadInnerXml, не имеют никакого смысла. Таким образом, в случае запуска XSLT в SgmlReader вы можете столкнуться с тем, что базовый механизм вызывает один из этих методов, но не получает ожидаемого результата. Также см. комментарий Алехандро о том, что ожидается от XSLT. 02.12.2010
  • & @Alejandro: я думал, что для этого и предназначен SgmlReader (т. е. обрабатывать искаженный HTML так же, как если бы он был эквивалентом XHTML, и все это в конкретном случае HTML). На самом деле, если вы посмотрите на трассировку, кажется, что ридер используется для внутреннего создания экземпляра System.Xml.XPath.XPathDocument, который используется скомпилированным XSL трансформировать под капотом. В любом случае, я попробую эти методы через какое-то время, просто чтобы убедиться, что происходит с ReadSubtree и др. Спасибо 02.12.2010

  • 2

    Пробовали ли вы использовать HTML Agility Pack вместо SgmlReader? Вы можете загрузить в него html и напрямую запустить преобразование. Я не уверен, что XML-документ создается внутри, хотя кажется, что это не так, вы, вероятно, захотите сравнить использование памяти и ЦП с методом преобразования, который вы пробовали и отбрасывали.

    //You already have your xslt loaded into var xslt...
    
    HtmlDocument doc = new HtmlDocument();
    doc.Load( ... );  //load your HTML doc, or use LoadXML from a string, etc  
    xslt.Transform(doc, xw);
    

    См. также этот вопрос: Как использовать пакет гибкости HTML

    30.11.2010
  • Спасибо, Филип, за ответ, но создание HTML DOM может занять много времени, а также потребуется дополнительная память. Я бы очень хотел избежать загрузки объектов в память и дополнительной обработки, потому что приложение должно работать на устройствах с ограниченными возможностями. Вот почему я искал способ передать HTML XMLReader напрямую в XSLT (но, учитывая обратную трассировку, кажется, что он создает System.Xml.XPath.XPathDocument внутренне, так что, возможно, любые оптимизации, которые я могу представить, просто пустая трата времени...) 02.12.2010
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..


    © 2024 nano-hash.ru, Nano Hash - криптовалюты, майнинг, программирование