繁体   English   中英

将XML转换为指定的顺序(DTD-> XSD)

[英]Transform XML into specified ordering (DTD -> XSD)

我有一个项目,我们要处理的主文件是一个旧的XML文件,其中的创建者创建了一个非常非结构化的DTD(所有元素都是可选的,并且可能出现0次或多次。更好的是,读取文件的应用程序实际上期望有很多所需的值)。 我已经根据已知的应用程序需求创建了一个XSD,并将无序元素列表移动到XSD中的序列中。

是否有一个简单的转换过程(例如XSLT),该过程可以获取旧的XML文件,并以指定的方式对其元素进行排序,以便我们可以使用新的XSD对其进行验证?

例:

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

进入

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

此外,子代可能还具有需要也按预期的新顺序排序的元素。 谢谢!

您可以以更具声明性的方式使用样式表中嵌入的“查找列表”,而不是指定要在模板中排序的所有元素:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
   xmlns:my="my-namespace" 
   exclude-result-prefixes="my">
  <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
  <my:Top>
    <my:A>
      <my:AA/>
      <my:AB/>
      <my:AC/>
    </my:A>
    <my:B/>
    <my:C/>
    <my:D/>
  </my:Top>
  <xsl:template match="my:*">
    <xsl:param name="source"/>
    <xsl:variable name="current-lookup-elem" select="current()"/>
    <xsl:for-each select="$source/*[name()=local-name($current-lookup-elem)]">
      <xsl:copy>
        <xsl:apply-templates select="$current-lookup-elem/*">
          <xsl:with-param name="source" select="current()"/>
        </xsl:apply-templates>
        <xsl:copy-of select="text()"/>
      </xsl:copy>
    </xsl:for-each>
  </xsl:template>
  <xsl:template match="/Top">
    <xsl:apply-templates select="document('')/*/my:*">
      <xsl:with-param name="source" select="/"/>
    </xsl:apply-templates>
  </xsl:template>
</xsl:stylesheet>

此示例:

<Top>
  <A>
    <AC/>
    <AA/>
  </A>
  <D/>
  <B/>
  <C>yyy</C>
  <A>
    <AB/>
    <AC/>
    <AA>xxx</AA>
  </A>
</Top>

将返回:

<Top>
    <A>
        <AA>xxx</AA>
        <AC/>
    </A>
    <A>
        <AA/>
        <AB/>
        <AC/>
    </A>
    <B/>
    <C>yyy</C>
    <D/>
</Top>

我假设您不想按字母顺序排列元素,而是按指定的顺序排列它们。 试试看-您将需要一个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-of xsl:copy ,然后从那里调用类似的模板以按顺序输出下一个级别。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM