我正在對一堆由第三方應用程式生成的 XML 檔案進行版本控制。不幸的是,這些檔案的保存方式通常會使版本控制比應有的更麻煩。他們可能會交換元素:
<root>
- <b>bar</b>
<a>foo</a>
<b>bar</b>
</root>
或重新排序屬性:
-<root a="foo" b="bar"/>
<root b="bar" a="foo"/>
或更改/洗掉縮進:
-<root a="foo" b="bar"/>
<root
a="foo"
b="bar"/>
需要明確的是,這些檔案不會混合文本和元素節點(如<a>foo <b>bar</b></a>),并且不同排序的檔案之間沒有語意差異,因此可以安全地以任何我們想要的方式重新排序它們。
我通過使用xsltproc和以下模式對元素進行排序來部分解決了這個問題:
<stylesheet version="1.0" xmlns="http://www.w3.org/1999/XSL/Transform">
<output method="xml" indent="yes" encoding="UTF-8"/>
<strip-space elements="*"/>
<template match="processing-instruction()|@*">
<copy>
<apply-templates select="node()|@*"/>
</copy>
</template>
<template match="*">
<copy>
<apply-templates select="@*"/>
<apply-templates>
<sort select="name()"/>
<sort select="@*[1]"/>
<sort select="@*[2]"/>
<sort select="@*[3]"/>
<sort select="@*[4]"/>
<sort select="@*[5]"/>
<sort select="@*[6]"/>
</apply-templates>
</copy>
</template>
</stylesheet>
However, I've recently learned that attribute ordering is not defined, so ordering by the six "first" attributes won't work in general. And of course this doesn't sort the attributes.
(I've used "normalize" in the title because I don't necessarily want to sort the elements in some particular way, it just seemed like the most obvious way to make sure the textual difference between two semantically identical files is empty.)
Is there some way to achieve such ordering?
Despite the name, this is different from XSLT sort by tag name and attribute value. The question includes only a single attribute, and the accepted solution isn't sufficiently general.
uj5u.com熱心網友回復:
這個練習的目的并不完全清楚。如果您只想“規范化”(規范化?)不同的檔案,以便元素及其屬性以相同的順序(和縮進)出現,您可以簡單地執行以下操作:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*">
<xsl:sort select="name()"/>
</xsl:apply-templates>
<xsl:apply-templates select="node()">
<xsl:sort select="name()"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
當這應用于以下輸入時:
XML 1
<input shape="circle" size="large" color="blue">
<shape>circle</shape>
<size>large</size>
<color>blue</color>
</input>
XML 2
<input color="red" size="small" shape="square">
<color>red</color>
<size>small</size>
<shape>square</shape>
</input>
結果將分別為:
結果 1
<?xml version="1.0" encoding="UTF-8"?>
<input color="blue" shape="circle" size="large">
<color>blue</color>
<shape>circle</shape>
<size>large</size>
</input>
結果 2
<?xml version="1.0" encoding="UTF-8"?>
<input color="red" shape="square" size="small">
<color>red</color>
<shape>square</shape>
<size>small</size>
</input>
Note:
Since the order of attributes is by definition insignificant, an XSLT processor is not obligated to follow the instruction to sort them. Hower, in practice most processors will.
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/359598.html
上一篇:通過XSD重新定義附加限制模式
