2013-12-17 1 views
1

Я использую банеры SaxonHE для процессоров XSLT 2.0, чтобы изменить последовательность элементов на требуемую последовательность с помощью XSD. Но не получить желаемый результат.
Моего файл XML является:Как сортировать элементы в соответствии с последовательностью, заданной в XSD-файле xshema с XSLT 2: выполнить-сортировать

<param xsi:type="Bank"> 
    <bankData name="ABC"/> 
    <branchAddress id="ABCB1">NY</branchAddress> 
    <legalAddress id="ABCL1">UK</legalAddress> 
</param>  

В соответствии с XSD, правильная последовательность для дочерних элементов паров тега bankData, legalAddress, branchAddress. Параметр тега может содержать данные любого типа. Таким образом, последовательность должна быть изменена, если тип атрибута «Банк»

Я использую этот код XSL, чтобы изменить последовательность:

<xsl:variable name="bankElementSeq" as="element()*"> 
    <bankData/><legalAddress/><branchAddress/> 
</xsl:variable> 
<xsl:template match="param/*"> 
    <xsl:if test="param/@xsi:type='Bank'"> 
     <xsl:perform-sort select="param/*"> 
      <xsl:sort select="index-of($bankElementSeq//node-name(.), node-name(.))"/> 
     </xsl:perform-sort> 
    </xsl:if> 
</xsl:template> 

Требуемая мощность является:

<param xsi:type="Bank"> 
    <bankData name="ABC"/> 
    <legalAddress id="ABCL1">UK</legalAddress> 
    <branchAddress id="ABCB1">NY</branchAddress> 
</param>  

Но я получение продукции как:

<param xsi:type="Bank"> 
</param>  

Детские элементы не написаны.
В чем может быть проблема?

+0

Там нет ничего в этом вопросе частности, Saxon, так что я удалил этот тег –

ответ

0

Давайте посмотрим на этот код более подробно:

<xsl:template match="param/*"> 
    <xsl:if test="param/@xsi:type='Bank'"> 
     <xsl:perform-sort select="param/*"> 
      <xsl:sort select="index-of($bankElementSeq//node-name(.), node-name(.))"/> 
     </xsl:perform-sort> 
    </xsl:if> 
</xsl:template> 

Во-первых, этот шаблон применяется к каждому ребенку парам в свою очередь. Это влияет на обработку обработанного элемента, это не влияет на обработку выбранных элементов. Чтобы переупорядочить дочерние элементы «param», вам нужна логика в шаблоне для элемента «param», а не для шаблона для его детей.

Во-вторых, в шаблоне у вас есть относительное выражение пути param/@ xsi: type. Это оценивается относительно узла контекста, который является дочерним элементом «param». Итак, вы ищете внука param, который сам по себе называется param. В вашем примере XML нет такого внука. Вы повторяете эту ошибку в выражении пути xsl: perform-sort/@ select.

Таким образом, вы могли бы на самом деле добиться того, что вы хотите, как это:

<xsl:template match="param[@xsi:type='Bank']"> 
    <xsl:perform-sort select="*"> 
     <xsl:sort select="index-of($bankElementSeq/node-name(.), node-name(.))"/> 
    </xsl:perform-sort>  
</xsl:template> 
+0

Теперь была написана работа с исполняемыми, но только дочерними элементами. Параметр tag был удален из вывода xml. – user2025527

+0

Хорошо.добавлен код копирования из кода Marcus, чтобы скопировать элемент param. user2025527

+0

У меня есть еще одна проблема, которая хочет заменить одно общее значение атрибута для любого тега. Старое значение атрибута - system = Legacy, которое необходимо изменить на system = AdvMig. Как это сделать в xslt 2.0? – user2025527

0

См. Решение @ MichaelKay для хорошего объяснения, почему ваш текущий подход не работает.

Я хотел бы предложить несколько иной подход. Он не пытается сортировать записи, а просто использует вашу вспомогательную переменную в итерации над дочерними тегами в param. Это должно быть функционально эквивалентно сейчас, но некоторые могут иметь некоторые преимущества в других настройках, в которых вы хотите только вывести подмножество тегов. Вы просто включали бы только нужные теги в переменную auxialiary и оставляли бы все остальные.

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet 
    version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" /> 

    <xsl:variable name="bankElementSeq" as="element()*"> 
    <bankData/><legalAddress/><branchAddress/> 
    </xsl:variable> 

    <!-- the following pattern restricts the match to exactly the type of param you want to modify --> 
    <xsl:template match="param[@xsi:type='Bank']"> 

    <xsl:copy>  
     <xsl:copy-of select="@*"/> 
     <xsl:variable name="param" select="."/> 

     <!-- iterate over the elements in the sorting order --> 
     <xsl:for-each select="$bankElementSeq">   
     <!-- and copy the found found by 'local-name' --> 
     <xsl:copy-of select="$param/*[local-name() = local-name(current())]"/> 
     </xsl:for-each> 

    </xsl:copy> 
    </xsl:template> 

</xsl:stylesheet> 
+0

его рабочими для дочерних элементов тега паров. Но атрибуты не копируются в новый xml. Параметром является .. без его атрибутов. – user2025527

+0

@ user2025527: Спасибо за подсказку. См. Мой обновленный XSLT выше. –

Смежные вопросы