2

XSLT を使用して要素名の一部を増分番号付きの別の要素名に変更することは可能ですか。

要素名を変更したいのと同じように、先頭に UPC_ を付けます

<product>
    <UPC_US>123</UPC_US>
    <UPC_UK>223</UPC_UK>
    <UPC_JP>345</UPC_JP>
    <other>unchange</other>
</product>
<product>
    <UPC_US>1234</UPC_US>
    <UPC_CA>1235</UPC_CA>
    <other>unchange</other>
</product>

これに?

<product>
    <UPC_1>123</UPC_1>
    <UPC_2>223</UPC_2>
    <UPC_3>345</UPC_3>
    <other>unchange</other>
</product>
<product>
    <UPC_1>1234</UPC_1>
    <UPC_2>1235</UPC_2>
    <other>unchange</other>
</product>
4

2 に答える 2

4

これは、XSLT を使用すると非常に簡単に実現できます。まず、UPCで始まる要素に一致するテンプレートを作成します。

<xsl:template match="product/*[starts-with(local-name(), 'UPC')]">

次に、要素の位置に基づいて、改訂された名前で新しい要素を作成します。

<xsl:element name="UPC_{position()}">

ここで名前を作成する際に「属性値テンプレート」を使用していることに注意してください。中括弧は、これが評価される式であり、文字通りの出力ではないことを示しています。

ここに完全な XSLT があります

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output method="xml" indent="yes"/>

   <xsl:template match="product/*[starts-with(local-name(), 'UPC')]">
      <xsl:element name="UPC_{position()}">
         <xsl:apply-templates select="@*|node()"/>
      </xsl:element>
   </xsl:template>

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

XML を適用すると、以下が出力されます。

<products>
   <product>
      <UPC_1>123</UPC_1>
      <UPC_2>223</UPC_2>
      <UPC_3>345</UPC_3>
      <other>unchange</other>
   </product>
   <product>
      <UPC_1>1234</UPC_1>
      <UPC_2>1235</UPC_2>
      <other>unchange</other>
   </product>
</products>

そうは言っても、UPC要素が常に最初の要素である場合にのみ機能します。これを入力として持っていた場合

<product>
    <UPC_US>123</UPC_US>
    <UPC_UK>223</UPC_UK>
    <UPC_JP>345</UPC_JP>
    <other>unchange</other>
</product>

出力は次のようになります

<products>
   <product>
      <UPC_1>123</UPC_1>
      <UPC_2>223</UPC_2>
      <other>unchange</other>
      <UPC_4>345</UPC_4>
   </product>
</products>

これが望ましくない場合は、代わりにxsl:numberを使用して要素を数えることができます。代わりにこの XSLT を試してください

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output method="xml" indent="yes"/>

   <xsl:template match="product/*[starts-with(local-name(), 'UPC')]">
      <xsl:variable name="count">
         <xsl:number count="*[starts-with(local-name(), 'UPC')]"/>
      </xsl:variable>
      <xsl:element name="UPC_{$count}">
         <xsl:apply-templates select="@*|node()"/>
      </xsl:element>
   </xsl:template>

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

この場合、2 番目の例では次のようになります。

<products>
    <product>
        <UPC_1>123</UPC_1>
        <UPC_2>223</UPC_2>
        <other>unchange</other>
        <UPC_3>345</UPC_3>
    </product>
</products>

どちらの場合も、Indentity Transform テンプレートを使用して他のすべての要素をそのままコピーすることに注意してください。

于 2013-03-28T22:17:14.403 に答える
1

はい、可能です。xsl:element新しい要素名を動的に作成できます。

于 2013-03-28T22:17:06.377 に答える