1

次のXML 1.0コードがあります

<oldEle userlabel="label1">
    <ele1>%02d.jpeg</ele1>
</oldEle>

<oldEle userlabel="label2">
    <ele1>%02d.tiff</ele1>
</oldEle>

xsl v1.0を使用して、oldEleごとにoldEleをjpegおよびtiffに変更したいと考えています。基本的に、xsl にこれを実行してもらいたい:

<JPEG userlabel="label1">
    <ele1>%02d.jpeg</ele1>
</JPEG>

<TIFF userlabel="label2">
    <ele1>%02d.tiff</ele1>
</TIFF>

私は次のことを試しましたが、うまくいきません:

<xsl:template match="/oldEle">
    <xsl:for-each select="/oldEle">
    <xsl:if test="contains(/oldEle/ele1,'jpeg')">
        <JPEG>
          <xsl:apply-templates select="@*|node()"/>
        </JPEG>      
    </xsl:if>      
    </xsl:for-each>
</xsl:template>

ありがとう!

4

2 に答える 2

0

ele1要素にピリオドが 1 つしか含まれないことを保証できる場合は、xpath 関数substring-afterを使用してファイル拡張子を抽出し、xsl:element関数を使用してその名前の新しい要素を作成できます。

<xsl:element name="{substring-after(ele1, '.')}">

ただし、大文字にも変換する必要があるため、余分な複雑さが必要になります.XSLT1.0では、これは面倒な変換機能によって実現されます.

<xsl:element 
   name="{translate(
     substring-after(ele1, '.'), 
     'abcdefghijklmnopqrstuvwxyz', 
     'ABCDEFGHIJKLMNOPQRSTUVWXYZ')}">

注意すべきもう 1 つの点は、 oldEleが XML のルート要素で/oldEleあることを意味するマッチングを行っていることです。整形式の XML ではルート要素を 1 つしか持てないため、これはおそらく望ましくありません。

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

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

   <xsl:template match="oldEle[contains(ele1, '.')]">
      <xsl:element name="{translate(substring-after(ele1, '.'), 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')}">
         <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に当てはめると

<root>
   <oldEle userlabel="label1">
      <ele1>%02d.jpeg</ele1>
   </oldEle>
   <oldEle userlabel="label2">
      <ele1>%02d.tiff</ele1>
   </oldEle>
</root>

以下が出力されます

<root>
   <JPEG userlabel="label1">
      <ele1>%02d.jpeg</ele1>
   </JPEG>
   <TIFF userlabel="label2">
      <ele1>%02d.tiff</ele1>
   </TIFF>
</root>

ただし、 ele1に複数のピリオドが含まれている場合、XSLT は失敗します。たとえば、次の XML について考えてみます。

<root>
   <oldEle userlabel="label1">
      <ele1>test.image1.jpeg</ele1>
   </oldEle>
   <oldEle userlabel="label2">
      <ele1>test.image2.tiff</ele1>
   </oldEle>
</root>

この場合、XSLT1.0 では、おそらくファイル拡張子を抽出するために再帰的な名前付きテンプレートが必要になります。

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

   <xsl:template match="oldEle[contains(ele1, '.')]">
      <xsl:variable name="extension">
         <xsl:call-template name="getExtension">
            <xsl:with-param name="text" select="ele1"/>
         </xsl:call-template>
      </xsl:variable>

      <xsl:element name="{translate($extension, 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')}">
         <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:template name="getExtension">
      <xsl:param name="text"/>
      <xsl:param name="delimiter" select="'.'"/>
      <xsl:choose>
         <xsl:when test="contains($text, $delimiter)">
            <xsl:call-template name="getExtension">
               <xsl:with-param name="text" select="substring-after($text, $delimiter)"/>
               <xsl:with-param name="delimiter" select="$delimiter"/>
            </xsl:call-template>
         </xsl:when>
         <xsl:otherwise>
            <xsl:value-of select="$text"/>
         </xsl:otherwise>
      </xsl:choose>
   </xsl:template>
</xsl:stylesheet>

これも同じ出力を生成します。

于 2012-06-05T08:30:19.383 に答える