Я думаю, что все, что вам нужно сделать, это изменить свой шаблон соответствия, чтобы проверить, существует ли HeaderText
узел
<xsl:template match="HeaderInformation[HeaderText]">
Если HeaderInformation
не имеет HeaderText
, тогда шаблон идентификации будет соответствовать ему, и тогда все останется неизменным.
Обратите внимание, меня смущают эти три строки
<xsl:copy-of select="HeaderText[last()]/following-sibling::*[following-sibling::LineItem]"/>
<xsl:apply-templates select="LineItem"/>
<xsl:copy-of select="LineItem/following-sibling::*"/>
Похоже, вы пытаетесь выбрать все после HeaderText
, но до LineItem
. Затем вы выбираете LineItem
, а затем все после этого. Но это действительно то же самое, что и сделать это:
<xsl:apply-templates select="HeaderText[last()]/following-sibling::*"/>
Поскольку у вас есть шаблон идентификации, выполнение xsl:apply-templates
здесь аналогично выполнению xsl:copy-of
. (И я предполагаю, что для LineItem
у вас действительно есть соответствующий шаблон, так что он будет иметь приоритет над шаблоном идентификации).
Кроме того, ваше <xsl:for-each select="HeaderText[generate-id() =
generate-id(key('header_text', Text)[1])]">
утверждение, включая его тело, на самом деле можно просто упростить до этого ...
<xsl:copy-of select="HeaderText[generate-id() = generate-id(key('header_text', Text)[1])]" />
Попробуйте это XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" standalone="yes" indent="yes"/>
<xsl:key name="header_text" match="HeaderText" use="Text"/>
<xsl:key name="line_text" match="LineText" use="Text"/>
<!-- Identity-Template für die nicht explizit benannten Elemente -->
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="HeaderInformation[HeaderText]">
<HeaderInformation>
<xsl:apply-templates select="HeaderText[1]/preceding-sibling::*"/>
<xsl:copy-of select="HeaderText[generate-id() = generate-id(key('header_text', Text)[1])]" />
<xsl:apply-templates select="HeaderText[last()]/following-sibling::*"/>
</HeaderInformation>
</xsl:template>
</xsl:stylesheet>
Сказав это, есть еще более простой подход, который вы можете использовать, и вместо того, чтобы явно копировать отдельные элементы, подумайте об удалении дублирующих элементов.
Попробуйте тоже XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" standalone="yes" indent="yes"/>
<xsl:key name="header_text" match="HeaderText" use="Text"/>
<xsl:key name="line_text" match="LineText" use="Text"/>
<!-- Identity-Template für die nicht explizit benannten Elemente -->
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="HeaderText[generate-id() != generate-id(key('header_text', Text)[1])]" />
</xsl:stylesheet>
У вас был бы аналогичный шаблон для LineText
и здесь.