0

xslt のバックグラウンドが非常に低く、次のような XML を変換する必要があります。

<row attribute1="1" attribute2="something" attribute3="somevalue">
<row attribute1="1" attribute2="something" attribute3="somevalue">
<row attribute1="2" attribute2="anotherthing" attribute3="somevalue">

次のようになります。

<row attribute1="1">
<row attribute1="2">

変換タスクには、さらに 2 つの要件があります。上記と同じ結果を得たいのですが、属性名を変更したいと思います。たとえば、次のようになります。

<row new_name_for_attribute1="1">
<row new_name_for_attribute1="2">

最後の要件は、メソッドが単一の属性 (前の例のように)、それらのサブセット (attribute1 と attribute3)、または行要素のすべての属性に適用できることです。

前もって感謝します。

4

2 に答える 2

2

XSLT の複雑さについて詳しく知りたい場合は、問題を解決するために使用できるMuenchian Groupingと呼ばれる手法について知りたいと思うかもしれません。個別の行を取得するには、attribute1で効果的にグループ化し、グループごとにグループ内の最初の要素を選択します。(または最初ではない要素を破棄します)。Muenchian Grouping は、XSLT 1.0 でこれを実現する最も効率的な方法です。

この場合、グループを示すキーを定義することから始めます。この場合は、attribute1でグループ化された要素です。

<xsl:key name="row" match="row" use="@attribute1" />

次に、個別の要素を選択する場合は、指定された属性のキーで最初に出現した行要素を選択します1

<xsl:apply-templates select="row[generate-id() = generate-id(key('row', @attribute1)[1])]" />

または、重複する行要素 (つまり、グループの最初ではない要素)を無視するテンプレートを使用することもできます。

<xsl:template match="row[generate-id() != generate-id(key('row', @attribute1)[1])]" />

このXSLTを試してください

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output method="xml" indent="yes"/>
   <xsl:key name="row" match="row" use="@attribute1" />

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

   <xsl:template match="row[generate-id() != generate-id(key('row', @attribute1)[1])]" />   
</xsl:stylesheet>

以下のXMLに当てはめると

<rows>
   <row attribute1="1" attribute2="something" attribute3="somevalue" />
   <row attribute1="1" attribute2="something" attribute3="somevalue" />
   <row attribute1="2" attribute2="anotherthing" attribute3="somevalue" />
</rows>

以下が出力されます

<rows>
   <row attribute1="1" attribute2="something" attribute3="somevalue"></row>
   <row attribute1="2" attribute2="anotherthing" attribute3="somevalue"></row>
</rows>

ljdelight の回答で説明されているように、XSLT を簡単に拡張して、属性の名前を変更したり、属性を除外したりできます。さらに、テストに 2 番目の属性を含めたい場合は、次のようにキーを拡張できます。

<xsl:key name="row" match="row" use="concat(@attribute1, '|', @attribute3)" />

重複を無視するために、テンプレートは次のようになります。

<xsl:template match="row
     [generate-id() != generate-id(key('row', concat(@attribute1, '|', @attribute3))[1])]" />  

ここで注意すべき唯一のことは、パイプ文字 | の使用です。区切り文字として。これは、属性値に出現しない限り、必要に応じて他の文字にすることができます。

于 2013-03-05T20:58:36.210 に答える
1

XML は簡単に変換できます。これは、xsl について調べて学習できる小さなコードです。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output method="xml" indent="yes" />
   <xsl:template match="@*|node()">
       <xsl:copy>
           <xsl:apply-templates select="@*|node()"/>
       </xsl:copy>
   </xsl:template>

   <!-- drop a row that matches a previous row of the same id -->
   <xsl:template match="row[ preceding-sibling::row/@attribute1 = @attribute1 ]" />

   <!-- do stuff with the row. this template is equivalent to the default template copy. -->
   <xsl:template match="row">
      <xsl:copy>
         <xsl:apply-templates select="@*|node()" />
      </xsl:copy>
   </xsl:template>

   <!-- drop attribute2 attributes -->
   <xsl:template match="@attribute2" />

   <!-- rename attribute1 -->
   <xsl:template match="@attribute1">
      <xsl:attribute name="new_name_for_attribute1">
         <xsl:value-of select="."/>
      </xsl:attribute>
   </xsl:template>
</xsl:stylesheet>

この入力の使用:

<table>
   <row attribute1="1" attribute2="something" attribute3="somevalue">
      <p>foo</p>
   </row>
   <row attribute1="1" attribute2="something" attribute3="somevalue">
      <p>bar</p>
   </row>
   <row attribute1="2" attribute2="anotherthing" attribute3="somevalue">
      <p>bazinga</p>
   </row>
</table>

この出力を取得します:

<table>
   <row new_name_for_attribute1="1" attribute3="somevalue">
      <p>foo</p>
   </row>
   <row new_name_for_attribute1="2" attribute3="somevalue">
      <p>bazinga</p>
   </row>
</table>
于 2013-03-05T10:24:06.843 に答える