Обновление: приведение гораздо более тщательного примера.
Первые два предложенных решения соответствовали тому, что я пытался сказать , а не . Я не могу знать местоположение, он должен иметь возможность просматривать все дерево документов. Таким образом, решение в этом направлении с / Books /, указанным в качестве контекста, не будет работать:
SELECT x.query('.') FROM @xml.nodes('/Books/*[not(@ID) or @ID = 5]') x1(x)
Оригинальный вопрос с лучшим примером:
Используя реализацию SQL Server 2005 XQuery, мне нужно выбрать все узлы в документе XML, по одному разу, и сохранить их исходную структуру, но только если у них отсутствует определенный атрибут или этот атрибут имеет определенное значение (переданное параметр). Запрос также должен работать со всем документом XML (по оси «потомок или сам»), а не с выбранной глубиной.
То есть каждый отдельный узел появится в результирующем документе, только если он и каждый из его предков пропустили атрибут или имеют атрибут с одним конкретным значением.
Например:
Если бы это был XML:
DECLARE @Xml XML
SET @Xml =
N'
<Library>
<Novels>
<Novel category="1">Novel1</Novel>
<Novel category="2">Novel2</Novel>
<Novel>Novel3</Novel>
<Novel category="4">Novel4</Novel>
</Novels>
<Encyclopedias>
<Encyclopedia>
<Volume>A-F</Volume>
<Volume category="2">G-L</Volume>
<Volume category="3">M-S</Volume>
<Volume category="4">T-Z</Volume>
</Encyclopedia>
</Encyclopedias>
<Dictionaries category="1">
<Dictionary>Webster</Dictionary>
<Dictionary>Oxford</Dictionary>
</Dictionaries>
</Library>
'
Параметр 1 для категории приведет к этому:
<Library>
<Novels>
<Novel category="1">Novel1</Novel>
<Novel>Novel3</Novel>
</Novels>
<Encyclopedias>
<Encyclopedia>
<Volume>A-F</Volume>
</Encyclopedia>
</Encyclopedias>
<Dictionaries category="1">
<Dictionary>Webster</Dictionary>
<Dictionary>Oxford</Dictionary>
</Dictionaries>
</Library>
Параметр 2 для категории приведет к этому:
<Library>
<Novels>
<Novel category="2">Novel2</Novel>
<Novel>Novel3</Novel>
</Novels>
<Encyclopedias>
<Encyclopedia>
<Volume>A-F</Volume>
<Volume category="2">G-L</Volume>
</Encyclopedia>
</Encyclopedias>
</Library>
Я знаю, что XSLT идеально подходит для этой работы, но это не вариант. Мы должны полностью выполнить это в SQL Server 2005. Любые реализации, не использующие XQuery, тоже подойдут, если это можно сделать полностью в T-SQL.