XSLT — определяет, был ли узел уже скопирован в результирующее дерево

#xslt #xslt-1.0

#xslt #xslt-1.0

Вопрос:

Использование xsltproc для очистки входного XML.

Подумайте о номере детали, ссылающемся на описание детали из случайных мест в документе. Мой XML-ввод плохо разработан, и в нем есть ссылки на номера деталей для описания деталей повсюду, без реального представления о том, где они расположены. Некоторые ссылки являются текстом в элементах, некоторые-в атрибутах, иногда значение атрибута меняется в зависимости от контекста. Атрибут, содержащий номер детали, не имеет согласованного имени, используемое имя изменяется в зависимости от значения других атрибутов. Может быть, я мог бы создать ключ, выбрав дюжину различных мест, содержащих номер детали, но это было бы беспорядочно. Я бы также беспокоился о непреднамеренном выборе неправильных предметов со сложными узорами.

Поэтому моя цель состоит в том, чтобы скопировать описания деталей, на которые имеются ссылки, в выходной документ только один раз (ссылки имеются не на все описания). Я могу вставлять тесты во все различные шаблоны, чтобы определить номер детали в контексте. Очень простым решением было бы просто проверить, был ли он уже скопирован в дерево результатов, и не копировать его снова. Но нет никакого способа отследить это?

План Б состоит в том, чтобы скопировать его несколько раз в дерево результатов, а затем выполнить второй проход по выходному документу, чтобы удалить дубликаты.

Комментарии:

1. Мне кажется, что план Б самый простой, безопасный и надежный, но, возможно, не самый эффективный.

2. Результирующее дерево в XSLT 1-это не какая-то структура данных, в которой можно идентифицировать узлы. Казалось бы, было бы проще определить первую ссылку в дереве ввода, хотя ваше описание звучит так, как будто это сложно. И также неясно, какую структуру результатов вы пытаетесь построить, если это простой список описания детали, то даже в XSLT 1 с использованием параметра, передающего уже обработанные узлы входного описания, плюс объединение обработанного в данный момент, может быть достаточно для устранения дубликатов и вывода списка в конце.

Ответ №1:

Использование темпорального языка в вопросе («уже было») — хороший признак того, что вы думаете об этом неправильно. На декларативном языке вы не должны думать в терминах порядка обработки.

То, что вы, вероятно, ищете, — это что-то вроде этого:

 lt;xsl:variable name="first-of-a-kind-part-references" as="node()*"gt;  lt;xsl:for-each-group select="f:all-part-references(/)"   group-by="f:get-referenced-part(.)/@id"gt;  lt;xsl:sequence select="current-group()[1]"/gt;  lt;/xsl:for-each-groupgt; lt;/xsl:variablegt;  

а затем при обработке ссылки на деталь

 lt;xsl:if test=". intersect $first-of-a-kind-part-references"gt;  ... lt;/xsl:ifgt;    

Комментарии:

1. «На декларативном языке вы не должны думать в терминах порядка обработки». Я согласен с концепцией в целом, но… Дело в том, что шаблоны выполняются в том порядке, в котором они применяются/вызывают другие шаблоны, поэтому вопрос «я уже делал это», по крайней мере, имеет смысл, если не законен. И если бы это было полностью правдой, никто бы никогда не получил сообщение об ошибке «Узел атрибута не может быть создан после дочернего элемента, содержащего элемент».

2. Приведенное сообщение об ошибке является сокращением для «Узел атрибута не может отображаться в последовательности результатов конструктора последовательности после элемента, текста, комментария или узла с инструкцией по обработке». При разработке сообщений об ошибках существует компромисс между тем, чтобы сделать сообщение легким для понимания и сделать его строго точным.

3. Боюсь, вы упускаете из виду мою мысль. Дело не в языке сообщения об ошибке. Речь идет об ограничении, которое представляет собой сообщение об ошибке. Ограничение, которое не существовало бы, если бы порядок обработки не был значительным.

4. Это правда, что спецификация определяет это условие ошибки, чтобы позволить процессорам последовательно выполнять инструкции в том порядке, в котором они написаны. Но это неправда, что спецификация гарантирует, что процессор выполнит их таким образом.

5. Но конечным результатом этого ограничения является то, что оно заставляет автора таблицы стилей «мыслить в терминах порядка обработки». На чисто декларативном языке порядок инструкций не имел бы значения.