[英]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.