将 xml 元素和属性名称更改为驼峰式
change xml element and attribute names to camelCase
我是 XSLT 的新手,想知道是否可以将 XML 元素和属性名称转换为驼峰式大小写?
我的 XML 负载如下所示:
<?xml version="1.0" encoding="utf8" ?>
<Output>
<Error>
<Status>0</Status>
<Details>No errors</Details>
</Error>
<Synopsis>
<Count>451</Count>
</Synopsis>
<BankAccounts>
<BankAccount AcctNo="103" CustName="Frank" BalanceAmount="" Inactive="N" NoOfAccounts="1" >
<Addresses>
<Address>ABC</Address>
<Address>XYZ</Address>
</Addresses>
</BankAccount>
<BankAccount AcctNo="101" CustName="Jane" BalanceAmount="10005" Inactive="N" NoOfAccounts="1" >
<Addresses>
<Address>LMN</Address>
<Address>QWE</Address>
</Addresses>
</BankAccount>
</BankAccounts>
</Output>
不幸的是我没有任何东西可以展示,因为我不知道如何去做....
谢谢
XSLT 1.0,直接方法
您可以内联 firstChar
变量,为了便于阅读,我介绍了它们。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="1.0">
<xsl:output method="xml" indent="yes"/>
<!--elements-->
<xsl:template match="node()">
<xsl:choose>
<!--elements-->
<xsl:when test="name() != ''">
<xsl:variable name="firstChar" select="translate(substring(name(),1,1),'ABCDEFGHIJKLMNOPQRSTUWXYZ','abcdefghijklmnopqrstuwxyz')"/>
<xsl:element name="{concat($firstChar, substring(name(),2))}">
<xsl:apply-templates select="@*|node()"/>
</xsl:element>
</xsl:when>
<!--values-->
<xsl:otherwise>
<xsl:copy-of select="."/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!--attributes-->
<xsl:template match="@*">
<xsl:variable name="firstChar" select="translate(substring(name(),1,1),'ABCDEFGHIJKLMNOPQRSTUWXYZ','abcdefghijklmnopqrstuwxyz')"/>
<xsl:attribute name="{concat($firstChar, substring(name(),2))}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
XSLT 1.0,用于将字符串转换为驼峰式命名模板
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="1.0">
<xsl:output method="xml" indent="yes"/>
<!--elements-->
<xsl:template match="node()">
<xsl:choose>
<!--elements-->
<xsl:when test="name() != ''">
<xsl:variable name="newName">
<xsl:call-template name="toCamelCase">
<xsl:with-param name="value" select="./name()"/>
</xsl:call-template>
</xsl:variable>
<xsl:element name="{$newName}">
<xsl:apply-templates select="@*|node()"/>
</xsl:element>
</xsl:when>
<!--values-->
<xsl:otherwise>
<xsl:copy-of select="."/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!--attributes-->
<xsl:template match="@*">
<xsl:variable name="newName">
<xsl:call-template name="toCamelCase">
<xsl:with-param name="value" select="./name()"/>
</xsl:call-template>
</xsl:variable>
<xsl:attribute name="{$newName}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
<!--named template that converts a string into camel case-->
<xsl:template name="toCamelCase">
<xsl:param name="value"/>
<xsl:variable name="firstChar" select="translate(substring($value,1,1),'ABCDEFGHIJKLMNOPQRSTUWXYZ','abcdefghijklmnopqrstuwxyz')"/>
<xsl:value-of select="concat($firstChar, substring($value,2))"/>
</xsl:template>
</xsl:stylesheet>
输出
<?xml version="1.0" encoding="UTF-8"?>
<output>
<error>
<status>0</status>
<details>No errors</details>
</error>
<synopsis>
<count>451</count>
</synopsis>
<bankAccounts>
<bankAccount acctNo="103"
custName="Frank"
balanceAmount=""
inactive="N"
noOfAccounts="1">
<addresses>
<address>ABC</address>
<address>XYZ</address>
</addresses>
</bankAccount>
<bankAccount acctNo="101"
custName="Jane"
balanceAmount="10005"
inactive="N"
noOfAccounts="1">
<addresses>
<address>LMN</address>
<address>QWE</address>
</addresses>
</bankAccount>
</bankAccounts>
</output>
对于 XSLT 2/3,我将使用身份转换加上模板匹配元素和属性节点,这些节点使用 lower-case
:
更改第一个字母
<xsl:template match="*">
<xsl:element name="{prefix-from-QName(node-name())}{':'[prefix-from-QName(node-name(current()))]}{lower-case(substring(local-name(), 1, 1))}{substring(local-name(), 2)}" namespace="{namespace-uri()}">
<xsl:apply-templates select="@*, node()"/>
</xsl:element>
</xsl:template>
<xsl:template match="@*">
<xsl:attribute name="{prefix-from-QName(node-name())}{':'[prefix-from-QName(node-name(current()))]}{lower-case(substring(local-name(), 1, 1))}{substring(local-name(), 2)}" namespace="{namespace-uri()}" select="."/>
</xsl:template>
在 XSLT 3 中,您可以通过声明 <xsl:mode on-no-match="shallow-copy"/>
(作为 xsl:stylesheet
或 xsl:transform
的顶级子项)将身份转换设置为基本模板,在 XSLT 2 中您需要拼写为
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
我是 XSLT 的新手,想知道是否可以将 XML 元素和属性名称转换为驼峰式大小写?
我的 XML 负载如下所示:
<?xml version="1.0" encoding="utf8" ?>
<Output>
<Error>
<Status>0</Status>
<Details>No errors</Details>
</Error>
<Synopsis>
<Count>451</Count>
</Synopsis>
<BankAccounts>
<BankAccount AcctNo="103" CustName="Frank" BalanceAmount="" Inactive="N" NoOfAccounts="1" >
<Addresses>
<Address>ABC</Address>
<Address>XYZ</Address>
</Addresses>
</BankAccount>
<BankAccount AcctNo="101" CustName="Jane" BalanceAmount="10005" Inactive="N" NoOfAccounts="1" >
<Addresses>
<Address>LMN</Address>
<Address>QWE</Address>
</Addresses>
</BankAccount>
</BankAccounts>
</Output>
不幸的是我没有任何东西可以展示,因为我不知道如何去做.... 谢谢
XSLT 1.0,直接方法
您可以内联 firstChar
变量,为了便于阅读,我介绍了它们。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="1.0">
<xsl:output method="xml" indent="yes"/>
<!--elements-->
<xsl:template match="node()">
<xsl:choose>
<!--elements-->
<xsl:when test="name() != ''">
<xsl:variable name="firstChar" select="translate(substring(name(),1,1),'ABCDEFGHIJKLMNOPQRSTUWXYZ','abcdefghijklmnopqrstuwxyz')"/>
<xsl:element name="{concat($firstChar, substring(name(),2))}">
<xsl:apply-templates select="@*|node()"/>
</xsl:element>
</xsl:when>
<!--values-->
<xsl:otherwise>
<xsl:copy-of select="."/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!--attributes-->
<xsl:template match="@*">
<xsl:variable name="firstChar" select="translate(substring(name(),1,1),'ABCDEFGHIJKLMNOPQRSTUWXYZ','abcdefghijklmnopqrstuwxyz')"/>
<xsl:attribute name="{concat($firstChar, substring(name(),2))}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
XSLT 1.0,用于将字符串转换为驼峰式命名模板
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="1.0">
<xsl:output method="xml" indent="yes"/>
<!--elements-->
<xsl:template match="node()">
<xsl:choose>
<!--elements-->
<xsl:when test="name() != ''">
<xsl:variable name="newName">
<xsl:call-template name="toCamelCase">
<xsl:with-param name="value" select="./name()"/>
</xsl:call-template>
</xsl:variable>
<xsl:element name="{$newName}">
<xsl:apply-templates select="@*|node()"/>
</xsl:element>
</xsl:when>
<!--values-->
<xsl:otherwise>
<xsl:copy-of select="."/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!--attributes-->
<xsl:template match="@*">
<xsl:variable name="newName">
<xsl:call-template name="toCamelCase">
<xsl:with-param name="value" select="./name()"/>
</xsl:call-template>
</xsl:variable>
<xsl:attribute name="{$newName}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
<!--named template that converts a string into camel case-->
<xsl:template name="toCamelCase">
<xsl:param name="value"/>
<xsl:variable name="firstChar" select="translate(substring($value,1,1),'ABCDEFGHIJKLMNOPQRSTUWXYZ','abcdefghijklmnopqrstuwxyz')"/>
<xsl:value-of select="concat($firstChar, substring($value,2))"/>
</xsl:template>
</xsl:stylesheet>
输出
<?xml version="1.0" encoding="UTF-8"?>
<output>
<error>
<status>0</status>
<details>No errors</details>
</error>
<synopsis>
<count>451</count>
</synopsis>
<bankAccounts>
<bankAccount acctNo="103"
custName="Frank"
balanceAmount=""
inactive="N"
noOfAccounts="1">
<addresses>
<address>ABC</address>
<address>XYZ</address>
</addresses>
</bankAccount>
<bankAccount acctNo="101"
custName="Jane"
balanceAmount="10005"
inactive="N"
noOfAccounts="1">
<addresses>
<address>LMN</address>
<address>QWE</address>
</addresses>
</bankAccount>
</bankAccounts>
</output>
对于 XSLT 2/3,我将使用身份转换加上模板匹配元素和属性节点,这些节点使用 lower-case
:
<xsl:template match="*">
<xsl:element name="{prefix-from-QName(node-name())}{':'[prefix-from-QName(node-name(current()))]}{lower-case(substring(local-name(), 1, 1))}{substring(local-name(), 2)}" namespace="{namespace-uri()}">
<xsl:apply-templates select="@*, node()"/>
</xsl:element>
</xsl:template>
<xsl:template match="@*">
<xsl:attribute name="{prefix-from-QName(node-name())}{':'[prefix-from-QName(node-name(current()))]}{lower-case(substring(local-name(), 1, 1))}{substring(local-name(), 2)}" namespace="{namespace-uri()}" select="."/>
</xsl:template>
在 XSLT 3 中,您可以通过声明 <xsl:mode on-no-match="shallow-copy"/>
(作为 xsl:stylesheet
或 xsl:transform
的顶级子项)将身份转换设置为基本模板,在 XSLT 2 中您需要拼写为
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>