Xslt 基于子元素修改元素';通过xsl获取的部分值

Xslt 基于子元素修改元素';通过xsl获取的部分值,xslt,xslt-1.0,Xslt,Xslt 1.0,我有以下XML1.0代码 <oldEle userlabel="label1"> <ele1>%02d.jpeg</ele1> </oldEle> <oldEle userlabel="label2"> <ele1>%02d.tiff</ele1> </oldEle> %02d.jpeg %02d.tiff 我想使用XSLV1.0将每个oldEle的oldEle更改为jpeg和

我有以下XML1.0代码

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

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

%02d.jpeg
%02d.tiff
我想使用XSLV1.0将每个oldEle的oldEle更改为jpeg和tiff。基本上,我希望xsl做到这一点:

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

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

%02d.jpeg
%02d.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>


谢谢

如果可以保证ele1元素只包含一个句号,则可以在之后使用xpath函数子字符串提取文件扩展名,然后使用xsl:element函数创建具有该名称的新元素

<xsl:element name="{substring-after(ele1, '.')}">
当应用于以下XML时

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

%02d.jpeg
%02d.tiff
以下是输出

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

%02d.jpeg
%02d.tiff
如果ele1包含多个句号,XSLT将失败。例如,考虑下面的XML

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

test.image1.jpeg
test.image2.tiff
在本例中,在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>

这也将生成相同的输出。

这里有一个非递归且更高效的XSLT 1.0解决方案,它可以成功地处理任意数量的图像格式扩展,假设它们是静态已知的

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

 <my:suffixes>
  <s>jpeg</s><s>JPEG</s>
  <s>tiff</s><s>TIFF</s>
  <s>giv</s><s>GIV</s>
  <s>png</s><s>PNG</s>
 </my:suffixes>

 <xsl:variable name="vSufs" select="document('')/*/my:suffixes/s"/>

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

 <xsl:template match="*">
   <xsl:variable name="vSufFound" select=
    "$vSufs[position() mod 2 = 1]
         [substring(translate(current()/ele1, ., ''),
                    string-length(translate(current()/ele1, ., ''))
                    )
         =
          '.'
         ]"/>
   <xsl:choose>
     <xsl:when test="not($vSufFound)">
      <xsl:call-template name="identity"/>
     </xsl:when>
     <xsl:otherwise>
       <xsl:element name="{$vSufFound/following-sibling::s[1]}">
         <xsl:apply-templates select="node()|@*"/>
       </xsl:element>
     </xsl:otherwise>
   </xsl:choose>
 </xsl:template>
</xsl:stylesheet>
<t>
    <oldEle userlabel="label1">
        <ele1>%02d.jpeg</ele1>
    </oldEle>
    <oldEle userlabel="label2">
        <ele1>%02d.tiff</ele1>
    </oldEle>
</t>
<root>
    <oldEle userlabel="label1">
        <ele1>test.image1.jpeg</ele1>
    </oldEle>
    <oldEle userlabel="label2">
        <ele1>test.image2.tiff</ele1>
    </oldEle>
</root>
再次生成正确的结果:

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

谢谢你的帮助。我在我的程序中尝试过,但仍然不起作用。当我在浏览器中尝试时,所有的值都打印出来了。xsl文件正是您上面提到的。xsl文件为:%02d.jpeg%02d.tiff如果使用
xml样式表
指令在浏览器中输出结果,则可能希望将结果显示为HTML,不是XML。我更进一步,但现在它一直给我相同的文本,例如,如果jpeg是第一个,所有的oldEle将是jpeg。。。我尝试了每种类型的图像类型,但仍然只得到所有oldEle的第一种类型。谢谢,对不起,我是xslt新手。我想我知道为什么xslt总是只使用第一个ext,例如jpeg。{translate(后面的子字符串(//sig:outputFileFormat,'.'),'abcdefghijklmnopqrstuvxyz','abcdefghijklmnopqrstuvxyz')}后面的子字符串试图从头开始重新匹配,因此它总是找到第一个ext…这很好。但我仍然无法让更简单的版本工作。它一直给我相同的文本,例如,如果jpeg是第一个,所有oldEle将是jpeg。。。我尝试了每种类型的图像类型,但仍然只得到所有oldEle的第一种类型。谢谢你的帮助。很抱歉,我是xslt新手。@Evan:您只需将xslt代码和源XML复制并粘贴到各自的文件中,然后运行转换,您就会得到与我完全相同的结果(所需的结果)。如果您使用不同的代码,那么没有人能够预先保证这些不同的代码会产生什么。请在我的答案中的两个XML文档上运行转换,并验证您是否得到了我报告的结果。如果这是否定的,那么可能是复制/粘贴错误,或者(不太可能)是使用了有缺陷的XSLT处理器。感谢Dimitre的帮助。我粘贴了,但它不起作用,这并不让我感到惊讶。我使用的是定制的xlt和xml模式。在我看来,蒂姆的建议会奏效的。这是我现在拥有的
$suf = substring($t, string-length($t) - string-length($suf) +1)