Преобразовать XML в указанный порядок (DTD -> XSD) - PullRequest
1 голос
/ 26 ноября 2009

У меня есть проект, в котором основным файлом, с которым мы имеем дело, является старый XML-файл, в котором создатель создал очень неструктурированный DTD (все элементы являются необязательными и могут встречаться 0 или более раз. Еще лучше приложение, которое читает файл на самом деле ожидает много значений по мере необходимости). Я создал XSD на основе известных требований приложения и переместил неупорядоченные списки элементов в последовательности в XSD.

Существует ли простой процесс преобразования (например, XSLT), который может взять старый XML-файл и упорядочить его элементы определенным образом, чтобы мы могли использовать новый XSD для его проверки?

Пример:

<Top>
  <A/>
  <D/>
  <B/>
  <C/>
  <A/>
</TOP>

INTO

<Top>
  <A/>
  <A/>
  <B/>
  <C/>
  <D/>
</TOP>

Также у потомков также могут быть элементы, которые также должны быть отсортированы в ожидаемом порядке новой последовательности. Спасибо!

Ответы [ 2 ]

6 голосов
/ 26 ноября 2009

Вместо того, чтобы указывать все элементы для заказа в шаблоне, вы можете использовать более декларативный способ «списка поиска», встроенного в таблицу стилей:*

вернет:

<Top>
    <A>
        <AA>xxx</AA>
        <AC/>
    </A>
    <A>
        <AA/>
        <AB/>
        <AC/>
    </A>
    <B/>
    <C>yyy</C>
    <D/>
</Top>
1 голос
/ 26 ноября 2009

Я предполагаю, что вы не хотите алфавитировать ваши элементы, а располагайте их в указанном вами порядке. Попробуйте это - вам понадобится процессор XSLT (например, Saxon ), и сохраните этот файл как * .xsl.

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

<xsl:template match="Top">
   <xsl:copy>
      <xsl:for-each select="A">
         <xsl:copy-of select="." />  
      </xsl:for-each> 
      <xsl:for-each select="B">
         <xsl:copy-of select="." />  
      </xsl:for-each>  
      <xsl:for-each select="C">
         <xsl:copy-of select="." />  
      </xsl:for-each>  
      <xsl:for-each select="D">
         <xsl:copy-of select="." />  
      </xsl:for-each>
   </xsl:copy>  
</xsl:template>

</xsl:stylesheet>

БОЛЬШОЕ предостережение: XML чувствителен к регистру, поэтому ваши теги <Top> и </TOP> не совпадают, поэтому у вас нет правильно сформированного XML, поэтому процессор XSLT выдает ошибку и завершает работу.

<xsl:copy-of> копирует соответствующий элемент и ВСЕ его дочерние элементы (включая атрибуты). Чтобы переупорядочить более глубокие уровни, вы можете заменить xsl:copy-of на xsl:copy, а затем вызвать аналогичный шаблон оттуда для вывода следующего уровня по порядку.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...