3

XSLT を使用して属性の順序を制御するにはどうすればよいですか?

入力 XML ドキュメントがあります。

入力 XML

<?xml version="1.0" encoding="UTF-8"?>
<allNames id="ID_0" b:type="a:UnstructuredName">
    <typeName>KnownBy</typeName>
    <startDate>2001-01-01-05:00</startDate>
    <fullName>ABCD 004 COMPANY INC</fullName>
</allNames>

これを変換するには、XSLT を適用する必要があります。

出力 XML

<?xml version="1.0" encoding="UTF-8"?>
<allNames  b:type="a:UnstructuredName"  id="ID_0">
    <typeName>KnownBy</typeName>
    <startDate>2001-01-01-05:00</startDate>
    <fullName>ABCD 004 COMPANY INC</fullName>
</allNames>

唯一の変更点は、要素内の属性の順序変更allNamesです。別の投稿を調べて、属性を注文する XSLT を書きましたが、全体を機能させる方法がわかりません。

XSLT

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions">
    <xsl:output method="xml" indent="yes"/>
    <xsl:variable name="attributes" select="document('mytest.xml')//attribute"/>
    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="*">
        <xsl:variable name="self" select="."/>
        <xsl:for-each select="$attributes">
            <xsl:apply-templates select="$self/@*[name()=current()]"/>
        </xsl:for-each>   
     </xsl:template>
</xsl:stylesheet>

mytest.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <attributes>
        <attribute>b:type</attribute>
        <attribute>id</attribute>
    </attributes>
4

2 に答える 2

8

XML 勧告に従って、属性の順序は重要ではありません。

start-tag または empty-element タグ内の属性指定の順序は重要ではないことに注意してください。

したがって、XSLT は、出力の属性の順序を制御する方法を提供しません。

W3C 勧告内の属性の順序

一般に、XML の推奨事項はすべて、属性の順序付けを重要ではないと見なしますが、アプリケーションで属性の順序付けが必要な場合は、XML 正規化の推奨事項またはCanonical XMLの推奨事項の属性処理に関するセクションを参照してください。ただし、標準の XSLT の外でこれを行う必要があります。

属性の順序付けの実装ハック

XML 属性に順序付けを課すことは本質的に欠陥があり、相互運用性に反し、XML 勧告と XML を操作するための確立された慣行の両方から完全に外れていることを認識しているにもかかわらず、属性の順序付けを制御する必要がある場合は、次のいくつかの方法があります。そのような制御を実装する...

Michael Kay がこの質問に対する別の回答で言及しているように、Saxon 9.5 (PE 以降) には、シリアライザーの属性の順序を制御できる XSLT 拡張機能があります。詳細saxon:attribute-orderについては、を参照してください。

標準 XSLT によって生成された XML を後処理できます。XML ライブラリ レベルの下で操作すると、もちろん、文字または文字列レベルの処理によって、属性の順序付けを字句的に完全に制御できます。

XML ライブラリによって提供される順序付けの実装の詳細に依存できます。たとえば、一部のライブラリは、属性の名前に従ってアルファベット順に属性を書き出すか、提供された属性の順序を保持します。明らかに、実装の詳細に依存することは本質的に信頼できません。とは言うものの、例えば、の実装はXMLStreamWriter.writeAttribute、将来、それらに与えられた属性の順序を尊重し続ける可能性があります。

最後に、XML 属性の順序付けに関するすべての質問に対する本当の答えをもう一度繰り返します。終了する前に...

XML 属性を順序付きとして扱うことは、XML 勧告に反するため、避ける必要があります。

于 2013-11-01T00:02:05.980 に答える
4

Saxon 9.5 (PE 以降) は、シリアライザーsaxon:attribute-orderによって生成される属性の順序を制御できるシリアライゼーション オプションを提供します。属性の順序は、正常な受信アプリケーションに影響を与えるべきではありませんが、一貫した順序付けにより、人間が読みやすい XML を向上させることができます。また、人間が読みやすくすることが XML の目的の 1 つであったため、これを追加するのが妥当な機能であると考えました。

于 2013-11-01T09:38:13.710 に答える