我有一个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>
答案 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)