Я хочу изменить порядок некоторых элементов XML. XML является сложным и генерируется отдельным процессом - я не платил за его изменение, поэтому я надеялся использовать XSLT для исправления порядка элементов.Изменение порядка элементов XML при сохранении структурной иерархии и атрибутов
Я не эксперт XSLT (!), Поэтому я искал некоторые фрагменты и нашел что-то, что с незначительными изменениями в соответствии с моим случаем, почти работает. В лучшем варианте, который у меня есть, в настоящее время выводятся элементы в правильном порядке, но удаляются все атрибуты.
Я создал простой xml и соответствующий xsl с соответствующими функциями моей проблемы.
Здесь (фиктивный) Пример XML:
<?xml version="1.0" encoding="UTF-8"?>
<Companies xmlns="company:fruit:ns" Version="1.0">
<Description>Some example companies and fruit shipments</Description>
<Company CompanyId="Acme">
<Description>Some example shipments</Description>
<Shipment Id="ABC">
<Description>Some apples</Description>
<Fruit>
<Apples>10</Apples>
</Fruit>
</Shipment>
<Shipment Id="DEF">
<Description>Some oranges and pears</Description>
<Fruit>
<Oranges>20</Oranges>
<Pears>20</Pears>
</Fruit>
</Shipment>
<Shipment Id="JKL">
<Description>Empty</Description>
<Fruit/>
</Shipment>
<Fruit/>
</Company>
<Fruit/>
</Companies>
Проблема заключается в том, что должно быть элемент фирмы-фрукты после компании-Описание элемента (вместо этого следует всем элементам отгрузки) и должно быть элементом «Компании-фрукты», который следует за элементом «Описание компаний» (вместо этого он соответствует всем элементам Компании-компании). Я использовал следующее преобразование XSL, чтобы исправить порядок элементов:
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0" xpath-default-namespace="company:fruit:ns">
<!-- See http://xsltbyexample.blogspot.com/2008/02/re-arrange-order-of-elements-in-xml.html -->
<xsl:output omit-xml-declaration="no" indent="yes" method="xml" encoding="utf-8"/>
<xsl:strip-space elements="*"/>
<xsl:template match="*">
<xsl:apply-templates select="self::*" mode="copy"/>
</xsl:template>
<xsl:template match="Company/Description">
<xsl:message>Matched Company Description</xsl:message>
<xsl:apply-templates select="self::*" mode="copy"/>
<xsl:apply-templates select="../Fruit" mode="copy"/>
</xsl:template>
<xsl:template match="Companies/Description">
<xsl:message>Matched Companies Description</xsl:message>
<xsl:apply-templates select="self::*" mode="copy"/>
<xsl:apply-templates select="../Fruit" mode="copy"/>
</xsl:template>
<xsl:template match="Company/Fruit"/>
<xsl:template match="Companies/Fruit"/>
<xsl:template match="*" mode="copy">
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="text()">
<xsl:value-of select="."/>
</xsl:template>
</xsl:stylesheet>
Результирующий XML имеет право упорядоченность, но большинство атрибутов были раздеты:
<?xml version="1.0" encoding="utf-8"?>
<Companies xmlns="company:fruit:ns">
<Description>Some example companies and fruit shipments</Description>
<Fruit/>
<Company>
<Description>Some example shipments</Description>
<Fruit/>
<Shipment>
<Description>Some apples</Description>
<Fruit>
<Apples>10</Apples>
</Fruit>
</Shipment>
<Shipment>
<Description>Some oranges and pears</Description>
<Fruit>
<Apples>20</Apples>
<Pears>20</Pears>
</Fruit>
</Shipment>
<Shipment>
<Description>Empty</Description>
<Fruit/>
</Shipment>
</Company>
</Companies>
Я хотел бы получить какие-либо рекомендации от Эксперты XSLT!
Когда вы копируете свой элемент с атрибутами, просто скопируйте их с помощью '. Это копирует все атрибуты из текущего узла в выходную позицию. Либо вы определяете другой шаблон, как тот, который соответствует 'text()', или вы помещаете эту команду в свой блок '' в шаблон режима копирования. –
Matthias
@ Matthias - спасибо за ваш быстрый и полезный ответ. Я попытался внести изменения, которые вы предлагаете, пробовав их в нескольких местах в xsl, но в целом он не имел желаемого эффекта. Возможно, я неправильно понял ваш комментарий .... – rugplots