使用子节点子字符串创建新节点

时间:2012-06-05 18:44:10

标签: xslt xslt-1.0

我有一个xml文档,如下所示:

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

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

我希望它是这样的:

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

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

我试过了。

<xsl:template match="//xmlns:oldNode[contains(//xmlsns:oldNode/root:ele1, '.')]">
  <xsl:element name="{translate(substring-after(//xmlns:ele1, '.'),
               'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')}">
      <xsl:apply-templates select="@*|node()"/>
  </xsl:element>
</xsl:template>

但只获得文件ext的第一个。例如如果jpeg是第一个,我会得到两个节点。有人可以提供专业建议,说明为什么这不起作用。

顺便说一下,我也试过这个但是同样的事情发生了:

<xsl:template match="//xmlns:oldNode[contains(//root:ele1, '.jpeg')]">
  <xsl:element name="JPEG">
      <xsl:apply-templates select="@*|node()"/>
  </xsl:element>
</xsl:template>

<xsl:template match="//xmlns:oldNode[contains(//root:ele1, '.tiff')]">
  <xsl:element name="TIFF">
      <xsl:apply-templates select="@*|node()"/>
  </xsl:element>
</xsl:template>

3 个答案:

答案 0 :(得分:1)

<xsl:template match="oldNode">
    <xsl:choose>
        <xsl:when test="contains(ele1,'.jpeg')">
            <xsl:element name="JPEG">
                <xsl:apply-templates select="@*|node()"/>
            </xsl:element>
        </xsl:when>
        <xsl:when test="contains(ele1,'.tiff')">
            <xsl:element name="TIFF">
                <xsl:apply-templates select="@*|node()"/>
            </xsl:element>
        </xsl:when>
    </xsl:choose>
</xsl:template>

答案 1 :(得分:1)

第一个问题是您的匹配模板

 <xsl:template match="//xmlns:oldNode[contains(//xmlsns:oldNode/root:ele1, '.')]">

特别是,使用 contains 元素,您可能不希望前面有//oldNode,因为这将开始寻找第一个 oldNode 亲戚到根元素。你真正想要的是找到相对于你当前匹配的元素的 ele1 元素

<xsl:template match="//oldNode[contains(ele1, '.')]">

(我不确定你的意思是 oldNode 还是 oldEle 。我也不确定你的命名空间在哪里,所以我没有在这里展示)。

第二个问题是 xsl:element ,因为你在这里做了类似的事情

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

由于 substring-after 中的//,它将相对于XML的根元素获取第一个 ele1 ,而不是一个相对于你当前元素。你可能需要这样做

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

尝试使用此模板

<xsl:template match="//oldNode[contains(ele1, '.')]">            
    <xsl:element name="{translate(substring-after(//ele1, '.'),            
           'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')}">            
       <xsl:apply-templates select="@*|node()"/>            
    </xsl:element>            
</xsl:template>   

同样,对于第二套模板,你应该做这样的事情

<xsl:template match="//oldNode[contains(ele1, '.jpeg')]"> 

答案 2 :(得分: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"/>

     <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>

在提供的XML文档上应用此转换时,会生成所需的正确结果:

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

<强>解释

在此转换中,我们使用以下XPath 1.0表达式来实现标准的XPath 2.0 ends-with($t, $suf)函数:

$suf = substring($t, string-length($t) - string-length($suf) +1)