具有相同节点名称的xsl无序列表

时间:2013-01-09 19:03:45

标签: xml xslt

我想将每个“string”节点打印为以下xml中的li项:

<soapenv:Envelope 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:soapenv="http://schemas.url.org/url/envelope/"
>
    <soapenv:Header>
        <MultiSpeakMsgHeader 
            Version="" UserID="" 
            Pwd="" AppName="xx" AppVersion="x" 
            Company="xxx" xmlns="http://www.url.org/Version_3.0"
        />
    </soapenv:Header>
    <soapenv:Body>
        <GetMethodsResponse xmlns="http://www.url.org/Version_3.0">
            <GetMethods>
                <string>GetDomainMembers</string>
                <string>GetDomainNames</string>
                <string>GetMethods</string>
                <string>pingURL</string>
                <string>GetAllMeters</string>
                <string>GetAllServiceLocations</string>
                <string>GetAllCustomers</string>
                <string>GetCustomerByCustId</string>
                <string>GetServiceLocationByAccountNo</string>
                <string>GetServiceLocationByMeterNo</string>
                <string>ReadingChangedNotification</string>
            </GetMethods>
        </GetMethodsResponse>
    </soapenv:Body>
</soapenv:Envelope>

我目前有以下xsl代码 -

<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:exslt="http://exslt.org/common"
>
    <xsl:output method="html" />

    <xsl:template match="/GetMethods">
        <ul>
            <xsl:for-each select="GetMethods/string">
                <li>
                    <xsl:value-of select="string"/><br/>
                </li>
            </xsl:for-each>    
        </ul>
    </xsl:template>
</xsl:stylesheet>

但所有这一切都是将每个字符串节点打印为一个没有列表格式的长行。任何帮助将不胜感激。

我想要这个简单的输出:

    <ul>
        <li>GetDomainMembers</li>
        <li>GetDomainNames</li>
        <li>GetMethods</li>
        <li>pingURL</li>
        <li>GetAllMeters</li>
        <li>GetAllServiceLocations</li>
        <li>GetAllCustomers</li>
        <li>GetCustomerByCustId</li>
        <li>GetServiceLocationByAccountNo</li>
        <li>GetServiceLocationByMeterNo</li>
        <li>ReadingChangedNotification</li>
    </ul>

我目前正在获取此输出(没有格式化):

                                          GetDomainMembers            GetDomainNames            GetMethods            pingURL            GetAllMeters            GetAllServiceLocations            GetAllCustomers            GetCustomerByCustId            GetServiceLocationByAccountNo            GetServiceLocationByMeterNo            ReadingChangedNotification                  

2 个答案:

答案 0 :(得分:2)

<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:exslt="http://exslt.org/common"
    xmlns:response="http://www.url.org/Version_3.0"
    exclude-result-prefixes="exslt response"
>
    <xsl:output method="html" />

    <xsl:template match="/">
        <xsl:apply-templates select="//response:GetMethods" />
    </xsl:template>

    <xsl:template match="response:GetMethods">
        <ul>
            <xsl:apply-templates select="response:string" />
        </ul>
    </xsl:template>

    <xsl:template match="response:string">
        <li>
            <xsl:value-of select="." />
        </li>
    </xsl:template>
</xsl:stylesheet>

注意:

  • 首先,我们必须知道您的响应元素所在的命名空间。在您的情况下,命名空间URI是http://www.url.org/Version_3.0,我们需要将其分配给前缀以使其在XSLT中可用。我选择拨打前缀response
  • 接下来我们需要控制XSLT的输出。通过直接选择<xsl:template match="/">进行处理,匹配根节点(//response:GetMethods)并定义下一步的位置,这是最简单的。
  • response:GetMethodsresponse:string的模板定义了转换的其余部分。
  • 最后,我们必须确保XML命名空间前缀不会出现在生成的HTML中。这就是exclude-result-prefixes的作用。
  • 请在此处查看:http://www.xmlplayground.com/kS1Cul
  • 您还可以阅读What are the differences between 'call-template' and 'apply-templates' in XSL?,我在那里稍微解释了<xsl:apply-templates>
  • 一般情况下,您应该避免撰写<xsl:for-each>并选择<xsl:apply-templates>

答案 1 :(得分:1)

您的给定输入中没有与模式"/GetMethods"匹配的元素。因此,您的XML可能正在由默认模板处理(尽管我们不知道没有看到您的XSLT的其余部分)。默认模板输出每个元素的文本内容。

要解决此问题,

  1. 您的匹配模式不应以/开头,因为GetMethods不是顶级元素。如果您的意思是//GetMethods,那么它将匹配任何地方发生的<GetMethods>元素(在没有命名空间中)。但模式GetMethods也是如此;开头的//是多余的。
  2. 您需要为GetMethods指定正确的命名空间。根据您的输入XML,GetMethods位于URI为http://www.test.org/Version_3.0的命名空间中。因此,您需要为该命名空间声明一个名称空间前缀(例如“test”)并在匹配模式中使用它:
  3. _

     <xsl:template match="test:GetMethods"
          xmlns:test="http://www.test.org/Version_3.0">...
    

    实际上,将名称空间声明(xmlns:test="...")移动到顶级<xsl:stylesheet>元素可能更实际(如果您还没有)。然后,test前缀将在您需要的样式表中的任何位置可用。