Код: Выделить всё
public class Attribute
{
public string? Key { get; set; }
public string? Value { get; set; }
public Attribute() {}
public Attribute(string key, string value)
{
this.Key = key;
this.Value = value;
}
}
public class Node
{
public string Tag { get; set; }
public string Content { get; set; }
public List[url=http://https://www.w3schools.com]w3schools[/url]
[img]img_girl.bmp[/img]
(Это все вводимые пользователем данные в Консоли)
- PRINT // — извлекает все текстовое содержимое документа.
- PRINT // html/body/p -> Выходы: «Text1», «Text2», «Text3»
- PRINT //html /body/table/tr/td -> Выходы: «11», «22», «33», «44»
- PRINT //html/body/p[2] -> Выходы: «Text2»;
- PRINT / /html/body/*[@id='table2'] -> Выходы: "33", "44"
- PRINT //html/body/p[@id='p3'] -> извежда: 'Text3'.
- PRINT //html/body/table[@id='table2']/tr[2]/td -> извежда: "44"
Это моя функция обхода:
Код: Выделить всё
private List Traverse(Node node, string[] segments, int index)
{
List matches = new List();
if (node == null) return matches;
if (index + 1 >= segments.Length)
{
if (!string.IsNullOrEmpty(node.Content))
{
matches.Add(node.Content);
}
foreach (Node child in node.Children)
{
matches.AddRange(Traverse(child, segments, index));
}
return matches;
}
string segment = segments[index];
if (segment.Contains("*"))
{
foreach (var child in node.Children)
{
matches.AddRange(Traverse(child, segments, index + 1));
}
}
else if (segment.Contains("@"))
{
int attributeStart = segment.IndexOf('@');
int attributeEnd = segment.IndexOf('=');
if (attributeStart != -1 && attributeEnd != -1)
{
string attributeName = segment.Substring(attributeStart + 1, attributeEnd - attributeStart - 1);
string attributeValue = segment.Substring(attributeEnd + 2, segment.Length - attributeEnd - 4);
foreach (var child in node.Children)
{
if (child.Attributes.Any(attr => attr.Key == attributeName && attr.Value == attributeValue))
{
matches.AddRange(Traverse(child, segments, index + 1));
}
}
}
else
{
Console.WriteLine("Invalid attribute format");
}
}
else if (segment.Contains("["))
{
int indexStart = segment.IndexOf("[");
int indexEnd = segment.IndexOf("]");
if (indexStart != -1 && indexEnd != -1)
{
string indexValue = segment.Substring(indexStart + 1, indexEnd - indexStart - 1);
if (int.TryParse(indexValue, out int indexNum))
{
if (indexNum >= 0 && indexNum < node.Children.Count)
{
matches.AddRange(Traverse(node.Children[indexNum], segments, index + 1));
}
else
{
Console.WriteLine($"Invalid index: {indexNum}");
}
}
else
{
Console.WriteLine($"Invalid index value: {indexValue}");
}
}
else
{
Console.WriteLine("Invalid index format");
}
}
else
{
foreach (var child in node.Children)
{
if (segments[index + 1] == child.Tag)
{
matches.AddRange(Traverse(child, segments, index + 1));
}
}
}
return matches;
}
Код: Выделить всё
//...
foreach (var child in node.Children)
{
if (segments[index + 1] == child.Tag)
{
matches.AddRange(Traverse(child, segments, index + 1));
}
}
//...
Но теперь, делая это таким образом, я могу искать определенные элементы, такие как //html/body/p[1].
Когда функция достигает оператора else и проходит через дочерние элементы узла (
Код: Выделить всё
node.Children)
segments[index + 1]
Затем выходит из цикла foreach и возвращаются совпадения. выполняется без содержимого.
Если кто-то сможет понять мою логику и помочь мне решить проблему.
Подробнее здесь: https://stackoverflow.com/questions/781 ... -content-b