Редактор (или плагин), который показывает текущий XPath с атрибутами тега при редактировании XML

В черновике образца XML:

<unit name="Alpha">
    <unit name="One">
         █1
    </unit>
    <unit name="Two">
         █2
    </unit>
</unit>

Я хочу найти способ отображения XPath, содержащего

  • unit@name="Alpha"/unit@name="One"когда курсор находится в позиции █1

или

  • unit@name="Alpha"/unit@name="Two"когда курсор находится в позиции █2

так что я могу редактировать большие файлы XML, не сворачивая их структуру и не читая атрибуты имени самостоятельно.

В идеале хотелось бы найти способ получить такой XPath в каком-нибудь бесплатном текстовом редакторе в Windows.

Это хорошая задача для плагина CudaText, если вы знаете Python. В плагине «CudaExt» уже есть команда, которая показывает текущий путь дерева кода в строке состояния: «Показать текущий путь в строке состояния». Вы можете сделать новый.
@RProgram — хм, это не столько о Python, сколько об изучении необходимых API и библиотек редактора. На данный момент мне нужно что-то готовое,
Я сделаю этот плагин, если вы сделаете базовый модуль Python, который находит строку XPath из текстовых строк и позиции курсора.
@RPgram - спасибо, если я зайду так далеко, то добавить остальное будет относительно несложно :) То, что вы упомянули, уже сделано в плагине Notepad++ XML Tools (на C++) и в плагине VS Code XML Tools. (скорее всего, на C#, но сейчас я не уверен, что его код общедоступен). Я имею в виду, что они уже отображают XPath, но как элементы без значений атрибутов. Я бы предпочел изменить это решение Notepad++. Так у тебя тоже все в порядке с C++?
Ну, мне нужен только код python, так как CudaText кроссплатформенный.

Ответы (2)

После отсутствия ответа я разработал простой скрипт Python для использования с плагином Python Script в редакторе Notepad++ . Его можно прикрепить к сочетанию клавиш или значку на панели инструментов*, чтобы отобразить все родительские XML-теги тега, находящегося в позиции курсора.

import re

matches = []
def match_found(m):
 matches.append(m.group(0))

editor.research('<[A-Za-z0-9_]+[^/>]*>|</[A-Za-z0-9_]+>', match_found, 0, 0, editor.getCurrentPos())
path = []
for m in matches:
 if m[:2] == "</":
  path.pop()
 elif m[-2:] != "/>":
  path.append(m)

msg = ""
for m in path:
 msg += m + "\n"

notepad.messageBox(msg, "Parents of current tag", 0)

*) из-за текущей внутренней проблемы плагина скрипт работает только тогда, когда он прикреплен ко второму или более высокому значку панели инструментов, добавленному этим плагином. С первой иконкой проблемы, прикрепите к ней что-нибудь и не нажимайте. Более эффективный способ — просто привязать сочетание клавиш через «Настройки» > «Сопоставление ярлыков» > «Команды плагинов» .

Попытаюсь адаптировать этот скрипт для создания команды CudaText в плагине CudaExt.
@RPgram — ОК :) только обратите внимание, что это быстрое и грязное решение, достаточное для моих нужд. Например, он не обрабатывает комментарии XML. Правильное решение может потребовать регулярного синтаксического анализа XML с использованием библиотеки XML, а затем, возможно, использовать созданную объектную модель документа для определения пути.

Редактор CudaText (бесплатный) имеет плагин CudaExt (устанавливается в Plugins/AddonManager), он дает команду «Дерево кодов: Показать текущий путь в строке состояния».

Для файла XML команда показывает путь в дереве XML, как на снимке экрана (желтоватая полоса внизу). Только примечание: курсор должен быть внутри <tag ... >, а не после него.

CudaText

Судя по снимку экрана, я боюсь, что путь, предоставленный плагином, не соответствует критериям, указанным в вопросе. Элементы пути не отображаются со своими атрибутами. Такой плагин (показ пути без атрибутов) есть во многих редакторах, но для меня он бесполезен, потому что если существует много похожих родительских разделов (в моем примере это будут "Альфа", "Бета", ....), вы не знаете, в каком из них вы сейчас находитесь, если они содержат сотни записей, таких как «один», «два», которые требуют прокрутки многих экранов, чтобы найти родительский тег XML.