D1m0nd
@D1m0nd
junior C# developer

Как в HtmlAgilityPack правильно использовать .SelectNodes(path);, когда я применяю его, но меняет моим элементам классы?

Есть следующий код(вначале я пишу в файл, чтобы убедиться что документ не изменен,) после применения метода
SelectNodes, он ставит последнню таблицу на превое место и меняет всем дочерним элементам классы
private void insertClass(HtmlAgilityPack.HtmlNode node, string currentClass, string path, string exp = null, bool oneIter = false) {
            // write to file before change
            var writer = File.CreateText("html3.html");
            writer.WriteLine(node.OuterHtml);
            writer.Dispose();
            var htmlArr = node.SelectNodes(path);
            if(htmlArr != null)
            {
                foreach (var item in htmlArr)
                {
                    Console.WriteLine(item.OuterHtml);
                    if (exp == null || item.OuterHtml.IndexOf(exp) != -1)
                    {
                        
                        item.Attributes["class"].Value = currentClass;
                        Console.WriteLine(item.OuterHtml);
                        if (oneIter)
                            return;
                    }

                }
            }
        }

Код вызова метода
var html = new HtmlAgilityPack.HtmlDocument();
            html.LoadHtml(htmlText);
            var document = html.DocumentNode;

            //ищем таблицу с счет фактурой
            //var node = searchNode(document, "Счет-фактура", "//div");

                //вставляем класс table что бы ее перевернуть
                insertClass(document, "tablec", "//table", "Сумма", true);


Код до изменения https://jsfiddle.net/bvo4s27z/
Код после изменения https://jsfiddle.net/sr37ewun/
  • Вопрос задан
  • 150 просмотров
Решения вопроса 1
D1m0nd
@D1m0nd Автор вопроса
junior C# developer
Крч я начал использовать физлер и все стало норм
пример
вас интересует строка с Счет-фактура, остальное забейте
обработку null я не ставил, так как это только тестовый пример

Если используете физлер хтмл агилити пак 1.2.0, как я, то установиет физлер 1.3.0, с версиями ниже будет выдавать ошибку
static void Main(string[] args)
        {
            var fileInfo = new FileInfo(PATH);
            string fullFilePath = fileInfo.FullName;
            string htmlText = string.Empty;
            try
            {
                htmlText = ParseDOCX(fileInfo);
            }
            catch (OpenXmlPackageException e)
            {
                if (e.ToString().Contains("Invalid Hyperlink"))
                {
                    using (FileStream fs = new FileStream(fullFilePath, FileMode.OpenOrCreate, FileAccess.ReadWrite))
                    {
                        UriFixer.FixInvalidUri(fs, brokenUri => FixUri(brokenUri));
                    }
                    htmlText = ParseDOCX(fileInfo);
                }
            }

            if (htmlText.IndexOf("Счет-фактура") != -1)
            {
                var html = new HtmlAgilityPack.HtmlDocument();
                html.LoadHtml(htmlText);
                var document = html.DocumentNode;
                //ищем таблицу с счет фактурой
                var node = searchNode(document, "Счет-фактура", "div");
                //вставляем класс table что бы ее перевернуть
                insertClass(node, "table", "table", "Сумма", true);
                node = searchNode(node, "Сумма", "table");
                //меняем шрифт
                insertClass(node, "changeTextIntable", "span");
                //меняем размер ячейки и их обводку
                insertClass(node, "changeTdItem", "td");

                deleteTag(document, "table", "br");
                htmlText = document.OuterHtml;
            }

            using (MemoryStream ms = new MemoryStream())
            {
                var c = ms.ToArray();
            }
        }

        /**
         * Ищет экземпляр Node в document по
         * @param document - исходный объект документа
         * @param keySearchValue -  текстовый ключ, по которому необходимо найти элемент, по типу в теге содержится слово счет фактура
         * @param tag - тег, чей объект необходимо найти, указывать нужно без дополнительных знаков, 
         * пример правильного запроса QuerySelectorAll("br")
         * 
         * @return {HtmlAgilityPack.HtmlNode} возвращает найденный экземпляр HtmlNode
         */
        private static HtmlAgilityPack.HtmlNode searchNode(HtmlAgilityPack.HtmlNode document, string keySearchValue, string tag)
        {
            var htmlArr = document.QuerySelectorAll(tag);

            foreach (var item in htmlArr)
            {
                if (item.InnerText.IndexOf(keySearchValue) != -1)
                {
                    return item;
                }
            }
            return null;
        }
        /**
         * Удаляет тег в определенной связи
         * 
         * @param node - связь , в которой происходит удаление
         * @param tag - тег по которому необходимо построить связь
         * @param delTag - тег, который необходимо удалить
         */
        private static void deleteTag(HtmlAgilityPack.HtmlNode node, string tag, string delTag)
        {
            var htmlArr = node.QuerySelectorAll(tag).ToArray();
            foreach (var item in htmlArr)
            {
                item.OuterHtml.Replace(delTag, string.Empty);
            }

        }
        /**
         * Вставляет в тег определенный класс
         * 
         *@param node - связь в которой необходимо произвести изменения
         *@param currendClass - связь , который вставляем
         *@param tag тег, чью связь необходимо найти 
         *@param exp выражение, по которому необходимо найти элемент
         *@param флаг указывающий на количество проходов по массиву
         */
        private static void insertClass(HtmlAgilityPack.HtmlNode node, string currentClass, string tag, string exp = null, bool oneIter = false)
        {
            var htmlArr = node.QuerySelectorAll(tag).ToArray();

            foreach (var item in htmlArr)
            {
                if (exp == null || item.OuterHtml.IndexOf(exp) != -1)
                {
                    foreach (var itemAttrib in item.Attributes)
                    {

                        if (itemAttrib.Name == "class")
                        {

                            itemAttrib.Value = currentClass;
                            if (oneIter)
                                return;
                        }
                    }
                }

            }

        }
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы