3 回答

TA貢獻(xiàn)2041條經(jīng)驗(yàn) 獲得超4個贊
很抱歉,但答案比“不能你不能”或“你為什么首先需要這樣做?”更為微妙。
簡短的回答是“DOM不允許你這樣做,但SAX會”。
這是因?yàn)镈OM不關(guān)心屬性順序,因?yàn)榫蜆?biāo)準(zhǔn)而言它是沒有意義的,并且當(dāng)XSL獲得輸入流時,信息已經(jīng)丟失。大多數(shù)XSL引擎實(shí)際上會優(yōu)雅地保留輸入流屬性順序(例如Xalan-C(在一種情況下除外)或Xalan-J(總是))。特別是如果你使用<xsl:copy*>。
在我所知的情況下,不保留屬性順序的情況是。 - 如果輸入流是DOM - Xalan-C:如果你按字面插入結(jié)果樹標(biāo)簽(例如<elem att1={@att1} .../>
以下是SAX的一個示例,用于記錄(也禁止DTD嘮叨)。
SAXParserFactory spf = SAXParserFactoryImpl.newInstance();
spf.setNamespaceAware(true);
spf.setValidating(false);
spf.setFeature("http://xml.org/sax/features/validation", false);
spf.setFeature("http://apache.org/xml/features/nonvalidating/load-dtd-grammar", false);
spf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
SAXParser sp = spf.newSAXParser() ;
Source src = new SAXSource ( sp.getXMLReader(), new InputSource( input.getAbsolutePath() ) ) ;
String resultFileName = input.getAbsolutePath().replaceAll(".xml$", ".cooked.xml" ) ;
Result result = new StreamResult( new File (resultFileName) ) ;
TransformerFactory tf = TransformerFactory.newInstance();
Source xsltSource = new StreamSource( new File ( COOKER_XSL ) );
xsl = tf.newTransformer( xsltSource ) ;
xsl.setParameter( "srcDocumentName", input.getName() ) ;
xsl.setParameter( "srcDocumentPath", input.getAbsolutePath() ) ;
xsl.transform(src, result );
我還想指出的是,在許多反對者的意圖存在的情況下,屬性順序做的事情。
回歸測試是一個明顯的例子。任何被稱為優(yōu)化編寫不太好的XSL的人都知道你通常希望確保“新”結(jié)果樹與“舊”結(jié)果樹相似或相同。當(dāng)結(jié)果樹大約有一百萬行時,XML diff工具證明過于笨拙......在這些情況下,保留屬性順序非常有幫助。
希望這可以幫助 ;-)

TA貢獻(xiàn)1818條經(jīng)驗(yàn) 獲得超8個贊
請參閱XML建議的第3.1節(jié)。它說,“請注意,start-tag或empty-element標(biāo)簽中屬性規(guī)范的順序并不重要?!?/p>
如果一個軟件需要XML元素上的屬性以特定順序出現(xiàn),那么該軟件不處理XML,它處理的文本看起來像表面上的XML。它需要修復(fù)。
如果無法修復(fù),并且您必須生成符合其要求的文件,則無法可靠地使用標(biāo)準(zhǔn)XML工具來生成這些文件。例如,您可以嘗試(按照您的建議)使用XSLT以定義的順序生成屬性,例如:
<test> <xsl:attribute name="foo"/> <xsl:attribute name="bar"/> <xsl:attribute name="baz"/></test>
只是發(fā)現(xiàn)XSLT處理器發(fā)出這樣的:
<test bar="" baz="" foo=""/>
因?yàn)樘幚砥魇褂玫腄OM按標(biāo)簽名稱按字母順序排序?qū)傩?。(這是XML DOM中常見但不通用的行為。)
但我想強(qiáng)調(diào)一些事情。如果某個軟件在某個方面違反了XML建議,則可能在其他方面違反了該建議。如果在以錯誤的順序提供屬性時它會中斷,如果使用單引號分隔屬性,或者屬性值包含字符實(shí)體,或者XML建議說XML文檔中的任何其他內(nèi)容,它可能也會中斷可以做到這個軟件的作者可能沒有想到。

TA貢獻(xiàn)1821條經(jīng)驗(yàn) 獲得超5個贊
不可能過分強(qiáng)調(diào)羅伯特羅斯尼剛剛說的話,但我會試試。;-)
國際標(biāo)準(zhǔn)的好處是,當(dāng)每個人都遵循它們時,生活是美好的。我們所有的軟件都和平相處。
XML必須是我們最重要的標(biāo)準(zhǔn)之一。它是像SOAP這樣的“舊網(wǎng)”東西的基礎(chǔ),還有像RSS和Atom這樣的“web 2.0”。這是因?yàn)閄ML能夠在不同平臺之間進(jìn)行互操作的明確標(biāo)準(zhǔn)。
如果我們一點(diǎn)一點(diǎn)地放棄XML,我們將陷入這樣一種情況,即XML的生產(chǎn)者將無法假設(shè)XML的使用者能夠使用他們的內(nèi)容。這將對該行業(yè)產(chǎn)生災(zāi)難性影響。
對于根據(jù)標(biāo)準(zhǔn)編寫不處理XML的代碼的任何人,我們應(yīng)該非常有力地推遲。我理解,在這些經(jīng)濟(jì)時代,人們不愿意冒犯“不”來冒犯客戶和商業(yè)伙伴。但在這種情況下,我認(rèn)為這是值得的。如果我們不得不為每個業(yè)務(wù)合作伙伴手工制作XML,那么我們的財(cái)務(wù)狀況會更差。
因此,不要“啟用”不了解XML的公司。向他們發(fā)送標(biāo)準(zhǔn),突出顯示相應(yīng)的行。他們需要不再認(rèn)為XML只是帶有尖括號的文本。它的行為與表示尖括號的文本不同。
這不是有借口的。即使最小的嵌入式設(shè)備也可以在其中使用全功能的XML解析器實(shí)現(xiàn)。我還沒有聽到過無法解析標(biāo)準(zhǔn)XML的充分理由,即使人們無法負(fù)擔(dān)全功能的DOM實(shí)現(xiàn)。
添加回答
舉報