-2

Martin の回答に関する質問: Martin Honnen の回答はうまく機能しますが、ルート要素では機能しません。ルート要素として「車」があるとしましょう:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="foo">
        <cars>
            <car1 />
            <car2 />
        </cars>
    </xsl:template>
</xsl:stylesheet>

そして、私は取得したい:

<xsl:template match="foo">
    <cars>
        <car1 />
        <car2 />
        <TANK />
    </cars>
</xsl:template>

このために、私は使用します:

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

何も変更せずに正確な入力を出力します。私は試すことができます:

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

ただし、次のように、スタイルシートの外側に TANK ノードを配置します。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="order">
    <cars>
        <car1/>
        <car2/>
    </cars>
</xsl:template>
</xsl:stylesheet><TANK/>

車内のTANK要素を取得する方法は?

元の質問: XML を変換するために使用する XSL があります。

XML_format1 -> XSL1 -> XML_format2

この最初の XSL ファイルを (2 番目の XSL を使用して) 変換して、3 番目の形式で XML を出力する 3 番目の XSL ファイルを取得する必要があります。要するに:

XSL1 -> XSL2 -> XSL3

XML_format1 -> XSL3 -> XML_format3

次のスタイルシートを使用して、最初の XSL のコンテンツをコピーし、特定のノードをスキップすることもできます。

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

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

<xsl:template match="//skipThisNode"/>

</xsl:stylesheet>

私の問題:これに加えて、いくつかのノードの構造を変更する(何かを追加する)必要もあります。

<car>
    <color>green</color>
    <fuel>petrol</fuel>
</car>

これに:

<car>
    <color>green</color>
    <fuel>petrol</fuel>
    <topSpeed>99</topSpeed>
</car>

LE: 次のように、子を追加する必要がある特定のノードに一致するテンプレートを作成できます。

<xsl:template match="car">
    <color>
        <!-- existing value-of -->  
    </color>
    <fuel>
         <!-- existing value-of --> 
    </fuel>
    <topSpeed>
        <!-- * new value-of * -->  
    </topSpeed>
</xsl:template>

しかし、これは行き過ぎているようです。私が望むものを達成するためのより簡単な方法はありますか?

4

1 に答える 1

4

むしろ使いたい

<xsl:param name="newSpeed" select="99"/>

<xsl:template match="car">
  <xsl:copy>
    <xsl:apply-templates/>
    <topSpeed>
      <xsl:value-of select="$newSpeed"/>
    </topSpeed>
  </xsl:copy>
</xsl:template>

carこれにより、処理チェーンが維持され、必要に応じて要素の子および子孫を変換または削除するためのテンプレートを追加できます。

[編集]入力が完全なスタイルシートのように見えるため、最新の要件を理解しているかどうかはわかりませんが、必要な出力として単一のテンプレートのみを示しています。したがって、次のような入力があると仮定します

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="order">
        <cars>
            <car1 />
            <car2 />
        </cars>
    </xsl:template>
</xsl:stylesheet>

xsl:templateの一致属性と、使用するテンプレート本体のリテラル結果要素の両方を変換したい

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="1.0">

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

  <xsl:template match="xsl:template[@match = 'order']/@match">
    <xsl:attribute name="{name()}">
      <xsl:text>foo</xsl:text>
    </xsl:attribute>
  </xsl:template>

  <xsl:template match="xsl:template[@match = 'order']/cars">
    <xsl:copy>
      <xsl:apply-templates/>
      <TANK/>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

そうすれば、結果が得られます(Saxon 6.5.5でテスト済み)

<?xml version="1.0" encoding="utf-8"?><xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:template match="foo">
        <cars>
            <car1/>
            <car2/>
        <TANK/></cars>
    </xsl:template>
</xsl:stylesheet>

うまくいけば、これはあなたが望むものです(適切なインデントが欠けている可能性があります)。

于 2012-05-17T10:31:08.403 に答える