我有以下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>
谢谢!
答案 0 :(得分:0)
如果你能保证 ele1 元素只包含一个句号,你可以使用xpath函数 substring-after 提取文件扩展名,然后使用 xsl:element 函数用于创建具有该名称的新元素
<xsl:element name="{substring-after(ele1, '.')}">
然而,需要额外的复杂性,因为你需要将它转换为大写,而在XSLT1.0中,这将通过繁琐的翻译函数来实现
<xsl:element
name="{translate(
substring-after(ele1, '.'),
'abcdefghijklmnopqrstuvwxyz',
'ABCDEFGHIJKLMNOPQRSTUVWXYZ')}">
另外需要注意的是,您在/oldEle
上匹配,这意味着 oldEle 是您XML的根元素。因为在格式良好的XML中只能有一个根元素,所以这可能不是你想要的。
这是完整的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>
这也会产生相同的输出。
答案 1 :(得分:0)
这是一个非递归和更高效的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>
在提供的XML文档上应用此转换时:
<t>
<oldEle userlabel="label1">
<ele1>%02d.jpeg</ele1>
</oldEle>
<oldEle userlabel="label2">
<ele1>%02d.tiff</ele1>
</oldEle>
</t>
产生了想要的正确结果:
<t>
<JPEG userlabel="label1">
<ele1>%02d.jpeg</ele1>
</JPEG>
<TIFF userlabel="label2">
<ele1>%02d.tiff</ele1>
</TIFF>
</t>
应用于以下XML文档时(ele
的字符串值中存在多个点字符:
<root>
<oldEle userlabel="label1">
<ele1>test.image1.jpeg</ele1>
</oldEle>
<oldEle userlabel="label2">
<ele1>test.image2.tiff</ele1>
</oldEle>
</root>
再次产生正确的结果:
<root>
<JPEG userlabel="label1">
<ele1>test.image1.jpeg</ele1>
</JPEG>
<TIFF userlabel="label2">
<ele1>test.image2.tiff</ele1>
</TIFF>
</root>
<强>解释强>:
在此转换中,我们使用以下XPath 1.0表达式来实现标准的XPath 2.0 ends-with($t, $suf)
函数:
$suf = substring($t, string-length($t) - string-length($suf) +1)