我有一个看起来像这样的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>
但只获取文件扩展的第一个,例如,如果 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>
<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>
第一个问题是匹配的模板
<xsl:template match="//xmlns:oldNode[contains(//xmlsns:oldNode/root:ele1, '.')]">
特别是,对于包含元素,您可能不希望//oldNode
位于前面,因为这将开始查找相对于根元素的第一个oldNode。你真正想要的是寻找相对于你当前匹配的元素的ele1元素
<xsl:template match="//oldNode[contains(ele1, '.')]">
(顺便说一下,我不确定你的意思是oldNode还是oldEle。我也不确定您的命名空间适合在哪里,所以我没有在这里展示它们)。
第二个问题是xsl:element,因为你在这里做类似的事情。
<xsl:element name="{translate(substring-after(//xmlns:ele1, '.'),
'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')}">
由于子字符串之后的//
,它将选取相对于 XML 根元素的第一个 ele1,而不是相对于当前元素的 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')]">
这是与你之前的问题相同的答案 - 这完全解决了旧的和现在的问题,并且没有使用递归:
<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)