У меня есть файл XML, который в основном выглядит так:
<products xmlns:xsd = "http://www.w3.org/2001/XMLSchema" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance">
<Product Id = "1">
<Product Id = "1_1">
<Attribute Name = "Whatever"></Attribute>
</Product>
<Attribute Name = "Identifier">NumberOne</Attribute>
</Product>
<Product Id = "2">
<Attribute Name = "Identifier">NumberTwo</Attribute>
</Product>
</products>
Что я хочу сделать, так это извлечь полные продукты. Product Node, выполнив поиск
<Attribute Name = "Identifier">SEARCH_TEXT</Attribute>
Так, например, для NumberOne я бы получил окружающие теги Product (Id="1") и их содержимое.
Пример: для текста поиска "NumberOne" желаемый результат:
<Product Id = "1">
<Product Id = "1_1">
<Attribute Name = "Whatever"></Attribute>
</Product>
<Attribute Name = "Identifier">NumberOne</Attribute>
</Product>
для текста поиска "NumberTwo" это будет
<Product Id = "2">
<Attribute Name = "Identifier">NumberTwo</Attribute>
</Product>
Я пробовал это регулярное выражение (Python):
<Product ((?!</Product>)[\S|\s])*<Attribute Name=\"Identifier\">NumberOne</Attribute>((?!</Product>)[\S|\s])*</Product>
Но это не работает из-за вложенных продуктов. У кого-нибудь есть подсказка для решения этой проблемы?
Я читал, что регулярное выражение - не самый умный подход к таким проблемам поиска XML. На самом деле продукты верхнего уровня весят больше, и мне нужно объединить два XML-файла, которые выглядят как мой пример. Поэтому я надеялся, что с помощью регулярных выражений я смогу решить это на уровне «строки», а не на уровне синтаксического анализатора XML, где мне может потребоваться подготовить эти сложные объекты перед созданием окончательного вывода XML. Просто найдите продукт верхнего уровня по этому значению идентификатора и захватите их полностью — независимо от того, что они содержат в противном случае.
Большое спасибо.
ОБНОВЛЯТЬ: Основываясь на решении Джека Флитинга - это то, что я использовал (XPath):
//products//Product[Attribute[@Name = "Identifier" and text() = "NumberOne"]]
Извините - я обновил свой пост.





Действительно, не стоит пытаться анализировать xml с помощью регулярных выражений. Использование xpath должно привести вас туда, если я правильно вас понимаю. Например,
//Product[.//*[. = "NumberOne"]]
должен вывести:
<Product Id = "1">
<Product Id = "1_1">
<Attribute Name = "Whatever"/>
</Product>
<Attribute Name = "Identifier">NumberOne</Attribute>
</Product>
и т. д.
Спасибо за подсказку! Ваше предложение вернет результат, если NumberOne будет значением в любом дочернем узле продукта. Работает так, как вы сказали - но можно ли сделать так, чтобы учитывалась именно эта иерархия? Проверить: products.Product.Attribute[Name==Identifier] == NumberOne Возвращать: products.Product
неважно: я думаю, это то, что мне нужно: //products//Product[Attribute[@Name = "Identifier" and text() = "NumberOne"]] Большое спасибо!!
Не совсем понятно: каков именно ваш ожидаемый результат?