将XML节点名称转换为大写(XSLT 1.0)

时间:2011-06-29 09:15:54

标签: xml xslt translate

我有许多XSLT样式表可以将某些XML转换为csv文件。 使用的XML文件是基于数据库列名生成的,这些列名在构建XML时曾经自动转换为UPPERCASE - 无法再完成(我们不使用TSQL-FOR XML来构建XML)。列名通常是大写和小写字母的混合。 由于所有样式表当前都引用了大写列名称,因此XPath查询失败。

而不是通过所有XSL样式表并手动将XPath查询更改为数据库列名称的情况 - 这将占用今年的大部分时间(!) 有没有办法将所有XML'Tag'名称转换为大写,所以你可以在文档中使用它们?

非常感谢任何帮助!!

谢谢! 安德鲁

一个例子: 下面将生成一个csv文件,右侧有关于行,但没有任何数据,因为xslt正在寻找“STRNAME”,当它作为“strName”存储在XML中时 我的XML:

<XMLWRAPPER>
   <STAFFTABLE>
      <ROW>
         <strName>Andrew</strName>
         <strSurname>Smith</strSurname>
         <intuserType>1</intUserType>
      </ROW>
      <ROW>
         <strName>Jackie</strName>
         <strSurname>collins</strSurname>
         <intuserType>2</intUserType>
      </ROW>
    </STAFFTABLE>
  </XMLWRAPPER>

和xslt:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" omit-xml-declaration="yes"/>

<xsl:template match="/">"First Name","Surname","User type"<xsl:text>&#013;</xsl:text>

    <xsl:for-each select="/XMLWRAPPER/STAFFTABLE/ROW">
        <xsl:value-of select="STRNAME"/>,<xsl:value-of select="STRSURNAME"/>,<xsl:value-of select="INTUSERTYPE"/><xsl:text>&#013;</xsl:text>
     </xsl:for-each>
</xsl:template>
</xsl:stylesheet>

2 个答案:

答案 0 :(得分:3)

在XSLT 1.0中,我会使用Identity Transformationtranslate()函数:

<xsl:stylesheet 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">

    <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
    <xsl:strip-space elements="*"/>

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

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

</xsl:stylesheet>

此变换仅为“大写”元素,而不是属性。只需将第二个模板的匹配模式更改为*|@*,就可以轻松将其扩展到属性。


根据以下评论和specstranslate()函数不适用于所有语言的案例转换。

答案 1 :(得分:2)

@empo的解决方案是,如果名称仅包含拉丁字符,则可以使用该解决方案。如果不是这种情况,可以使用类似的XSLT 2.0转换,用标准的XPath 2.0函数 upper-case() 替换@ empo解决方案中的translate()函数。

此外,如果您只有几个sylesheets,修改样式表本身以处理混合字符名称可能要容易得多:

那是:

而不是

<xsl:template match="SOMENAME">

使用

 <xsl:template 
   match="*['SOMENAME' = translate(., $Lowercase, $Uppercase)]">