Преобразование личности
Преобразование данных |
---|
Концепции |
Языки трансформации |
Техники и трансформации |
Приложения |
Связанный |
Эта статья нуждается в дополнительных цитатах для проверки . ( декабрь 2022 г. ) |
— Преобразование идентичности это преобразование данных , которое копирует исходные данные в целевые данные без изменений.
Преобразование идентичности считается важным процессом при создании многократно используемой библиотеки преобразований . различные фильтры преобразования данных Создав библиотеку вариантов преобразования базовой идентичности, можно легко поддерживать . Эти фильтры могут быть объединены в цепочку в формате, аналогичном UNIX каналам оболочки .
Примеры рекурсивных преобразований
[ редактировать ]«Копирование с рекурсией» позволяет, изменяя небольшие части кода, создавать совершенно новые и разные выходные данные, фильтруя или обновляя входные данные. Понимая «идентичность посредством рекурсии», мы можем понять фильтры.
Использование XSLT
[ редактировать ]Наиболее часто упоминаемым примером преобразования идентичности (для XSLT версии 1.0) является преобразование «copy.xsl», выраженное в XSLT . Это преобразование использует команду xsl:copy. [1] для выполнения преобразования личности:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Этот шаблон работает путем сопоставления всех атрибутов ( @* ) и других узлов ( node() ), копирования каждого сопоставленного узла, а затем применения преобразования идентичности ко всем атрибутам и дочерним узлам контекстного узла. Это рекурсивно спускается по дереву элементов и выводит все структуры в той же структуре, в которой они были найдены в исходном файле, с учетом ограничений того, какая информация считается значимой в модели данных XPath . Поскольку node() соответствует тексту, инструкциям по обработке, корню и комментариям, а также элементам, копируются все узлы XML.
Более явная версия тождественного преобразования:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="@*|*|processing-instruction()|comment()">
<xsl:copy>
<xsl:apply-templates select="*|@*|text()|processing-instruction()|comment()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Эта версия эквивалентна первой, но явно перечисляет типы узлов XML, которые она будет копировать. Обе версии копируют данные, которые не нужны для большинства случаев использования XML (например, комментарии).
XSLT 3.0
[ редактировать ]XSLT 3.0 [2] указывает атрибут «нет совпадений» xsl:mode
инструкция, которая позволяет объявить преобразование идентификатора, а не реализовать его как явное правило шаблона. Конкретно:
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:mode on-no-match="shallow-copy" />
</xsl:stylesheet>
по сути эквивалентен предыдущим правилам шаблона. См. описание мелкого копирования в стандарте XSLT 3.0. [3] для получения подробной информации.
Наконец, обратите внимание, что детали разметки, такие как использование разделов CDATA или порядок атрибутов, не обязательно сохраняются в выходных данных, поскольку эта информация не является частью модели данных XPath . Чтобы отобразить разметку CDATA в выходных данных, таблица стилей XSLT, содержащая шаблон преобразования идентичности ( а не сам шаблон преобразования идентичности), должна использовать метод xsl:output
атрибут под названием cdata-section-elements
.
cdata-section-elements
задает список имен элементов, чьи дочерние текстовые узлы должны выводиться с использованием разделов CDATA.
[1]
Например:
<xsl:output method="xml" encoding="utf-8" cdata-section-elements="element-name-1 element-name-2"/>
Использование XQuery
[ редактировать ]XQuery может определять рекурсивные функции. Следующий пример функции XQuery копирует входные данные непосредственно в выходные без изменений.

declare function local:copy($element as element()) {
element {node-name($element)}
{$element/@*,
for $child in $element/node()
return if ($child instance of element())
then local:copy($child)
else $child
}
};

Той же функции можно добиться, используя преобразование в стиле typeswitch.
xquery version "1.0";
(: copy the input to the output without modification :)
declare function local:copy($input as item()*) as item()* {
for $node in $input
return
typeswitch($node)
case document-node()
return
document {
local:copy($node/node())
}
case element()
return
element {name($node)} {
(: output each attribute in this element :)
for $att in $node/@*
return
attribute {name($att)} {$att}
,
(: output all the sub-elements of this element recursively :)
for $child in $node
return local:copy($child/node())
}
(: otherwise pass it through. Used for text(), comments, and PIs :)
default return $node
};
Преобразование typeswitch в некоторых случаях предпочтительнее, поскольку его можно легко изменить, просто добавив оператор case для любого элемента, требующего специальной обработки.
Нерекурсивные преобразования
[ редактировать ]Два простых и наглядных преобразования «копировать все».
Использование XSLT
[ редактировать ]<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:copy-of select="."/>
</xsl:template>
</xsl:stylesheet>
Использование XPoc
[ редактировать ]<p:pipeline name="pipeline" xmlns:p="http://www.w3.org/ns/xproc">
<p:identity/>
</p:pipeline>
Здесь есть одно важное замечание об идентичности XPoc : в качестве входных данных он может принимать либо один документ, как в этом примере, либо последовательность документов.
Более сложные примеры
[ редактировать ]Обычно преобразование идентичности используется в качестве основы, на которой можно вносить локальные изменения.
Удалить преобразование именованного элемента
[ редактировать ]Использование XSLT
[ редактировать ]Преобразование идентичности можно изменить, чтобы скопировать все из входного дерева в выходное дерево, кроме данного узла. Например, следующая команда скопирует все из входных данных в выходные, кроме номера социального страхования:
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<!-- remove all social security numbers -->
<xsl:template match="PersonSSNID"/>
Использование XQuery
[ редактировать ] declare function local:copy-filter-elements($element as element(),
$element-name as xs:string*) as element() {
element {node-name($element) }
{ $element/@*,
for $child in $element/node()[not(name(.)=$element-name)]
return if ($child instance of element())
then local:copy-filter-elements($child,$element-name)
else $child
}
};
Чтобы вызвать это, нужно добавить:
$filtered-output := local:copy-filter-elements($input, 'PersonSSNID')
Использование XPoc
[ редактировать ]<p:pipeline name="pipeline" xmlns:p="http://www.w3.org/ns/xproc">
<p:identity/>
<p:delete match="PersonSSNID"/>
</p:pipeline>
См. также
[ редактировать ]Дальнейшее чтение
[ редактировать ]- Поваренная книга XSLT , O'Reilly Media, Inc., 1 декабря 2002 г., Сал Мангано, ISBN 0-596-00372-2
- Присцилла Уолмсли, XQuery , O'Reilly Media, Inc., Глава 8 Функции — Рекурсивные функции — страница 109