Если вам нужно переименовать каждый узел элемента, то обычный способ - написать шаблон для каждого элемента, выполняющего это микропреобразование. В любом случае я бы использовал буквальные элементы результата, например
<xsl:template match="Document">
<Transformed>
<xsl:apply-templates/>
</Transformed>
</xsl:template>
, а не xsl:element
. Непонятно, что вы хотите сохранить или где, по вашему мнению, для потоковой передачи для вашего первого примера требуются эти шаблоны, это кажется естественным решением XSLT для вашей задачи преобразования, с потоковой передачей или без нее.
Единственное использование из xsl:element
имеет смысл исключить некоторые шаблоны, например,
<xsl:template match="Number | Lines | Line">
<xsl:element name="Document{local-name()}">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
, но неясно, является ли этот шаблон переименования частью упрощения вашего образца или реальным требованием.
Единственное изменение, которое вы не можете сделать в чистом сопоставлении шаблонов на основе элементов, - это изменение содержимого, которое вы выполняете с помощью
<xsl:template match="/Document/Header/Type">
<xsl:element name="DocumentType">
<xsl:value-of select="if (text()='3') then 'P' else 'K'"/>
</xsl:element>
</xsl:template>
, в этом случае вам нужно будет добавить шаблон для дочернего элемента text()
, например (с expand-text="yes"
на месте)
<xsl:template match="Document/Header/Type/text()">{if (. = 3) then 'P' else 'K'}</xsl:template>
или я бы хотел использовать
<xsl:template match="Document/Header/Type/text()[. = 3]">P</xsl:template>
<xsl:template match="Document/Header/Type/text()">K</xsl:template>
На основании ваших комментариев вы хотите сократить второй показанный вами образец XSLT, как я уже сказал. , Я не вижу необходимости использовать xsl:element
; что касается xsl:choose
, я думаю, вы можете просто написать соответствующий шаблон:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs" version="3.0">
<xsl:strip-space elements="*"/>
<xsl:output indent="yes"/>
<xsl:mode streamable="yes"/>
<xsl:template match="/*">
<Transformed>
<xsl:apply-templates/>
</Transformed>
</xsl:template>
<xsl:template match="Document/*[not(self::Lines)]">
<xsl:apply-templates select="copy-of()" mode="non-streamable"/>
</xsl:template>
<xsl:template match="Header" mode="non-streamable">
<DocumentHeader>
<DocumentNumber>
<xsl:value-of select="Number"/>
</DocumentNumber>
<xsl:if test="string-length(Type) > 0">
<DocumentType>
<xsl:value-of select="if (Type='3') then 'P' else 'K'"/>
</DocumentType>
</xsl:if>
</DocumentHeader>
</xsl:template>
<xsl:template match="Lines">
<DocumentLines>
<xsl:apply-templates select="Line!copy-of()" mode="non-streamable"/>
</DocumentLines>
</xsl:template>
<xsl:template match="Line" mode="non-streamable">
<Line>
<LineNumber>
<xsl:value-of select="LineNumber"/>
</LineNumber>
</Line>
</xsl:template>
<xsl:template match="Summary" mode="non-streamable">
<DocumentTotal>
<xsl:value-of select="Total"/>
</DocumentTotal>
</xsl:template>
</xsl:stylesheet>