0

私がxml.com抱えている問題を示すために、からサンプルを取得しました。

私はこのXMLを持っています:

<?xml version="1.0"?>

<!--slightly modified source from xml.com -->

<winelist xmlns="urn:somesite:api:base">

    <wine grape="Chardonnay">
        <winery>Lindeman's</winery>
        <product>Bin 65</product>
        <year>1998</year>
        <prices>
        <list>6.99</list>
            <discounted>5.99</discounted>
            <case>71.50</case>
        </prices>
    </wine>

    <wine grape="Chardonnay">
        <winery>Benziger</winery>
        <product>Carneros</product>
        <year>1997</year>
        <prices>
            <list>10.99</list>
            <discounted>9.50</discounted>
            <case>114.00</case>
        </prices>
    </wine>

    <wine grape="Cabernet">
        <winery>Duckpond</winery>
        <product>Merit Selection</product>
        <year>1996</year>
        <prices>
            <list>13.99</list>
            <discounted>11.99</discounted>
            <case>143.50</case>
        </prices>
    </wine>

    <wine grape="Chardonnay">
        <winery>Kendall Jackson</winery>
        <product>Vintner's Reserve</product>
        <year>1998</year>
        <prices>
            <list>12.50</list>
            <discounted>9.99</discounted>
            <case>115.00</case>
        </prices>
    </wine>

</winelist>

そして、この XSL:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

    <xsl:template match="winelist">
        <xsl:copy>
            <xsl:apply-templates>
                <xsl:sort data-type="number" select="prices/discounted"/>
            </xsl:apply-templates>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="*">
        <xsl:copy>
            <xsl:apply-templates/>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

割引価格で要素を並べ替えようとしてwineいますが、変換された XML は、最初にワインリストから名前空間を削除しない限り (つまり、<winelist>.

手作業による名前空間の削除を適用する必要がないように、XSLT をどのように変更できますか?

また、変換された XML のワイン エンティティには、元のgrape属性がありません。これらはどのように保存できますか?コメントも同様です (ただし、それほど重要ではありません)。

最初に別の変換を使用してすべての名前空間を削除することもできますが、この 2 段階の解決策はあまり好きではなく、他の XML ソースの問題の原因になる可能性があると思います。

誰かがここで私を助けることができますか?

4

2 に答える 2

0

必要な作業は、名前空間を XSLT に追加し、match="*"テンプレートを変更して恒等変換にすることだけです。

例:

<xsl:stylesheet xmlns:x="urn:somesite:api:base" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:template match="x:winelist">
        <xsl:copy>
            <xsl:apply-templates>
                <xsl:sort data-type="number" select="x:prices/x:discounted"/>
            </xsl:apply-templates>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

名前空間が不明な場合の例local-name()(Xalan および Saxon 6.5.5 でテスト済み):

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:template match="*[local-name()='winelist']">
        <xsl:copy>
            <xsl:apply-templates>
                <xsl:sort data-type="number" select="*[local-name()='prices']/*[local-name()='discounted']"/>
            </xsl:apply-templates>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>
于 2013-06-14T17:06:09.140 に答える
-1

まず、入力 XML の忠実なコピーを作成するには、次のコードを使用します (「恒等変換」と呼ばれます)。

 <xsl:template match="@*|*|processing-instruction()|comment()">
    <xsl:copy>
      <xsl:apply-templates select="@*|*|text()|processing-instruction()|comment()"/>
    </xsl:copy>
  </xsl:template>

次に、マッチャーが名前空間を無視するようにするには (それが本当に必要な場合)、ローカル名で一致させることができます。

<xsl:template match="*[local-name()='winelist']">

または、XSLT に名前空間を認識させ、その名前空間で明示的に一致させることもできます。これは、より一般的な方法です。このようにしたくない唯一の理由は、名前空間が事前にわからない場合です。

<xsl:stylesheet xmlns:w="urn:somesite:api:base">
...
   <xsl:template match="w:wine">
     ...
于 2013-06-14T17:05:10.560 に答える