How to include space in XML tag/element which gets

2019-01-18 05:34发布

This question already has an answer here:

I have an XML which gets transformed with an XSLT into an Excel sheet on a webpage. The element tags in XML becomes column headers in Excel. There are columns which would like to have spaces. We don't like underscores or hyphens coming in Excel sheet headers. How can I incorporate space in an XML tag/element? I tried putting   or %20 or #&20; etc. (all kinds of syntax) but all of them shows error on XML editor itself saying this hexadecimal character is not allowed.

My XML is

<ClientArray>
  <Client>
    <LastName>Aanonsen</LastName>
    <FirstName>Fred</FirstName>
    <Additional Remarks><Additional Remarks>
  </Client>

I want a space between Additional and Remarks in the tag. Please help. Thanks in advance.

2条回答
孤傲高冷的网名
2楼-- · 2019-01-18 05:44

How to I incorporate space in an XML tag/element? I tried putting or %20 or &#20; etc etc . (all kinds of syntax) but all of them shows error on xml editor itself saying this hexadecimal character is not allowed

You can't. The W3C XML specification defines strictly the syntax of names. A name can only start with a letter character (this includes underscore, then the next characters can be letter characters ot numbers or the hyphen, but the space is a delimiter and is not allowed as part of any name.

More precisely, here are the exact rules from the spec:

[4a]    NameChar    ::=    NameStartChar | "-" | "." | [0-9] | #xB7 | [#x0300-#x036F] | [#x203F-#x2040] 
[5]    Name    ::=    NameStartChar (NameChar)* 

To overcome this restriction you have to modify your XSLT transformation so that it outputs as Excell column names more convenient to read strings than XML names.

查看更多
你好瞎i
3楼-- · 2019-01-18 06:02

Besides Dimitre's exact answer, you could use some pattern like in this stylesheet:

 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text"/>
    <xsl:template match="Client/*" name="space-capital">
        <xsl:param name="pLetters"
                   select="translate(name(),'qwertyuiopasdfghjklzxcvbnm','')"/>
        <xsl:param name="pString" select="name()"/>
        <xsl:param name="pOut" select="''"/>
        <xsl:choose>
            <xsl:when test="$pString != ''">
                <xsl:variable name="vFirst" select="substring($pString,1,1)"/>
                <xsl:call-template name="space-capital">
                    <xsl:with-param name="pLetters" select="$pLetters"/>
                    <xsl:with-param name="pString"
                                               select="substring($pString,2)"/>
                    <xsl:with-param name="pOut"
                         select="concat($pOut,
                                        substring(' ',1,contains($pLetters,
                                                                 $vFirst)
                                                        and
                                                        $pOut != ''),
                                        $vFirst
                                       )"/>
                </xsl:call-template>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="concat($pOut,' : ',.,'&#xA;')"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
</xsl:stylesheet>

With this proper input:

<ClientArray>
  <Client>
    <LastName>Aanonsen</LastName>
    <FirstName>Fred</FirstName>
    <AdditionalRemarks>Something</AdditionalRemarks>
  </Client>
</ClientArray>

Output:

Last Name : Aanonsen
First Name : Fred
Additional Remarks : Something

In XPath 2.0:

string-join(/*/*/*/concat(
                (: This is the expression you need :)
                     replace(name(),
                             '(\P{Lu})(\p{Lu})',
                             '$1 $2'),
              (: the rest is just to mimic the result :)
                     ' : ',.),
            '&#xA;')
查看更多
登录 后发表回答