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

发布于 2024-11-17 11:03:27 字数 1513 浏览 2 评论 0原文

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

而不是检查所有 XSL 样式表并手动将 XPath 查询更改为数据库列名称的大小写 - 这将花费今年的大部分时间(!) 有没有办法将所有 XML“标签”名称转换为大写,以便您可以在文档中使用它们?

非常感谢任何帮助!

谢谢你! 安德鲁

举个例子: 下面将生成一个 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>

I have many XSLT stylesheet(s) that transform some XML into a csv file.
The XML files used are generated based on database column names which used to be converted automatically to UPPERCASE when the XML was being built - which can no longer be done (we are no using TSQL-FOR XML to build the XML). The column names are Generally a mixture of uppercase and lowercase letters.
As all Stylesheets currently reference Uppercase column names, the XPath queries are failing.

Instead of going through ALL XSL stylesheets and manually changing the XPath queries to the case of the database column names - which would take most of this year(!)
Is there any way to convert all the XML 'Tag' names to Uppercase, so you can use them in the document?

Any help is greatly appreciated!!

Thank You!
Andrew

An example:
The below will generate a csv file with the right about Of rows, but without any data, as the xslt is looking for "STRNAME", when it is stored in The XML as "strName"
my 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>

and the 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>
</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>
</xsl:text>
     </xsl:for-each>
</xsl:template>
</xsl:stylesheet>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

待天淡蓝洁白时 2024-11-24 11:03:27

在 XSLT 1.0 中,我将使用 身份转换translate() 函数:

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

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


根据下面的评论和规范translate()< /code> 函数并不是所有语言中大小写转换的充分解决方案。

In XSLT 1.0 I would use the Identity Transformation and the translate() function:

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

This transform will "upper case" elements only, not the attributes. It is easy anyway extend it to attributes just by changing the match pattern of the second template to *|@*.


As per the comments below and the specs, translate() function is not a sufficient solution for case conversion in all languages.

┊风居住的梦幻卍 2024-11-24 11:03:27

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

另外,如果您只有几个样式表,则修改样式表本身来处理混合大小写的名称可能会更容易:

即:

而不是

使用

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

@empo 's solution is the one that can be used if the names consisted only of latin characters. If this isn't the case one can use a similar XSLT 2.0 transformation which replaces the translate() function in @empo's solution with the standard XPath 2.0 function upper-case().

Also, if you have just a few sylesheets, it may be much easier to modify the stylesheets themselves to handle mix-cased names:

That is:

Instead of

<xsl:template match="SOMENAME">

use:

 <xsl:template 
   match="*['SOMENAME' = translate(., $Lowercase, $Uppercase)]">
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文