Member 12692000 Ответов: 1

Проблема в последовательной программе проверки узлов с последовательными атрибутами?


Я пытаюсь найти несколько последовательных узлов <xref ref-type="bibr" rid="ref...">...</xref> (когда есть 3 или больше) в файле, которые разделены запятой или пробелом, и запишите их в файл журнала.

Примечание: последовательные узлы, которые я пытаюсь идентифицировать, должны иметь соответствующие значения rid, увеличенные на +1 минус текст ссылка. Вот небольшой пример файла https://codeshare.io/5wOjlK

и желаемый результат таков
<xref ref-type="bibr" rid="ref2">[2]</xref>, <xref ref-type="bibr" rid="ref3">[3]</xref>, <xref ref-type="bibr" rid="ref4">[4]</xref>


<xref ref-type="bibr" rid="ref11">[11]</xref>, <xref ref-type="bibr" rid="ref12">[12]</xref> <xref ref-type="bibr" rid="ref13">[13]</xref>


вот код, который я использую https://codeshare.io/ar6mPA Но он показывает ошибку типа dtd not found, как я могу ее игнорировать.Я попробовал использовать приведенный ниже код

Что я уже пробовал:

FileStream xmlStream = new FileStream(@"D:\test\12345.XML", FileMode.Open, FileAccess.Read);
XmlReaderSettings settings = new XmlReaderSettings();
settings.XmlResolver = null;
settings.ProhibitDtd = false;
XmlReader reader = XmlTextReader.Create(xmlStream, settings);
XmlDocument doc = new XmlDocument();
doc.Load(reader);


вместо

XmlDocument doc = new XmlDocument();
doc.PreserveWhitespace = true;
doc.Load(@"D:\test\12345.XML");

Но сейчас он показывает только первый матч...Я в замешательстве.. Кто-нибудь может помочь, пожалуйста...

1 Ответов

Рейтинг:
0

Maciej Los

Я предпочитаю использовать Класс XDocument[^] что очень "гибко", когда есть необходимость реализовать пользовательский метод поиска. Видеть:

XmlReaderSettings settings = new XmlReaderSettings();
settings.DtdProcessing = DtdProcessing.Parse;

XDocument xdoc = XDocument.Load(XmlReader.Create("fullfilename.xml", settings));

var cons = xdoc.Descendants("xref")
    .GroupBy(x=>x.Parent)
    .Select(grp=> new
        {
            Parent = grp.Key,
            ConsecutiveNodes = grp.Select((n, i)=> new
                {
                    Index = i+1,
                    Node = n
                }),
            Count = grp.Count()
        })
    .ToList();

Console.WriteLine("3 or more consecutive nodes:");
foreach(var o in cons)
{
    if (o.Count>2)
    {
        Console.WriteLine("{0}", new string('=', 30));
        Console.WriteLine("Found in: {0} ... {1}", o.Parent.ToString().Substring(0,15), o.Parent.ToString().Substring(o.Parent.ToString().Length-15,15));
        Console.WriteLine("{0}", new string('-', 50));
        foreach (var c in o.ConsecutiveNodes)
        {
            //Console.WriteLine("{0}", c.Node);
            Console.WriteLine("Original rid value [{0}] will be replaced with [{1}]", c.Node.Attribute("rid").Value, c.Index);
            c.Node.Attribute("rid").Value = c.Index.ToString();
        }
    }
}


Выше код выводит:
3 or more consecutive nodes:
==============================
Found in: <p>In this stud ... 15]</xref>.</p>
--------------------------------------------------
Original rid value [ref2] will be replaced with [1]
Original rid value [ref3] will be replaced with [2]
Original rid value [ref4] will be replaced with [3]
Original rid value [ref20] will be replaced with [4]
Original rid value [ref3] will be replaced with [5]
Original rid value [ref15] will be replaced with [6]
==============================
Found in: <p>The measurin ... cattering..</p>
--------------------------------------------------
Original rid value [ref11] will be replaced with [1]
Original rid value [ref12] will be replaced with [2]
Original rid value [ref13] will be replaced with [3]
Original rid value [ref4] will be replaced with [4]
Original rid value [T2] will be replaced with [5]


Для получения дополнительной информации, пожалуйста, смотрите:
XDocument.Метод Загрузки (XmlReader) (System.Xml.Linq)[^]
Свойства xmlreadersettings.Свойство DtdProcessing (System.Xml)[^]

Не стесняйтесь менять код в соответствии с вашими потребностями. Удачи вам!


Member 12692000

Привет Мацей, спасибо за ваш пост...кстати, не могли бы вы объяснить эту часть
.Select(grp=> new
{
Parent = grp.Key,
ConsecutiveNodes = grp.Select((n, i)=> new
{
Index = i+1,
Node = n
}),
Count = grp.Count()
})

Я не получил этого...также почему он показывает значения rid, отличные от [ref...]? как я могу получить только значения [ref...] (которые являются 3 последовательными узлами или более), как желаемый результат....

Maciej Los

Что ж... Я не был уверен, что вы подразумеваете под последовательными узлами... Вероятно, вы хотите получить только те узлы, атрибут которых [rid] содержит слово [ref].
Измените этот фрагмент кода:
xdoc.Descendants("xref")
.Where(x=>x.Attribute("rid").Value.Contains("ref")) //<-- condition has been added!
.GroupBy(x=>x.Parent)


Что касается вашего вопроса...
Чтобы иметь возможность получить последовательные узлы (один за другим), нам нужно сгруппировать их по их родителям (в данном случае [p] узлам). Выше select satatement получает родительский узел и все узлы [xref] этого родителя и добавляет индекс, чтобы иметь возможность изменить атрибут [rid].

Member 12692000

Спасибо за ваш ответ...Не могли бы вы оказать мне последнюю услугу?..
Вместо того чтобы показывать все [мпог] с текстом [Ссылка] он должен показать только [мпог] из [ссылка] с последовательных значений, т. е.
Original rid value [ref2] will be replaced with [1]
Original rid value [ref3] will be replaced with [2]
Original rid value [ref4] will be replaced with [3]
Original rid value [ref20] will be replaced with [4]
Original rid value [ref3] will be replaced with [5]
Original rid value [ref15] will be replaced with [6]

должно быть

Original rid value [ref2] will be replaced with [1]
Original rid value [ref3] will be replaced with [2]
Original rid value [ref4] will be replaced with [3]

и так далее...

Maciej Los

Ооххх! Вы имеете в виду последовательный, если rid является последовательным: ref2; ref3; ref4, но не узлом [xref]...

Member 12692000

да

Karthik_Mahalingam

5

Member 12692000

где вы взяли 5, как в [ref5] в этой строке?

Maciej Los

5 означает: 5 звезд (см. правый верхний угол моего ответа). Это называется системой голосования.

Member 12692000

Ладно, я все понял

Maciej Los

Спасибо, Картик

Member 12692000

Существует серьезная проблема с вашим кодом, которую я недавно обнаружил...Если есть, скажем, а <p> узел, который выглядит следующим образом
<p><xref ref-type="bibr" rid="ref20">[20]</xref>, and <xref ref-type="bibr" rid="ref21">[21]</xref> <xref ref-type="bibr" rid="ref22">[22]</xref> are in a table
тогда это также принимается в качестве допустимого вывода,
когда есть 3 или более <xref ref-type="bibr" rid="ref..> узлы, которые разделены либо a space или a comma and a space только тогда они должны рассматриваться как последовательные узлы(и их значения rid должны быть последовательными, как ref2, ref3, ref4)...

Maciej Los

Это совершенно другое требование, чем первоначальный вопрос. Я постараюсь тебе помочь, но чуть позже. Я сейчас очень занят.

Member 12692000

ОК...