样式API XML响应

时间:2018-03-22 22:57:49

标签: xml xslt

我有以下示例响应,我需要格式化,但我看到的所有示例都不匹配所以我完全迷失了将其转换为XSLT。我想要的是一个易于人类阅读的简单表格。

<?xml version="1.0" encoding="utf-8"?>
<ApiResponse Status="OK" xmlns="http://api.domain.com/xml.response">
  <Errors />
  <Warnings />
  <RequestedCommand>namecheap.users.getpricing</RequestedCommand>
  <CommandResponse Type="namecheap.users.getPricing">
    <UserGetPricingResult>
      <ProductType Name="domains">
        <ProductCategory Name="register">
          <Product Name="com">
            <Price Duration="1" DurationType="YEAR" Price="10.98" PricingType="MULTIPLE" AdditionalCost="0.18" RegularPrice="10.98" RegularPriceType="MULTIPLE" RegularAdditionalCost="0.18" RegularAdditionalCostType="MULTIPLE" YourPrice="10.98" YourPriceType="MULTIPLE" YourAdditonalCost="0.18" YourAdditonalCostType="MULTIPLE" PromotionPrice="0.0" Currency="USD" />
            <Price Duration="2" DurationType="YEAR" Price="10.88" PricingType="MULTIPLE" AdditionalCost="0.18" RegularPrice="10.88" RegularPriceType="MULTIPLE" RegularAdditionalCost="0.18" RegularAdditionalCostType="MULTIPLE" YourPrice="10.88" YourPriceType="MULTIPLE" YourAdditonalCost="0.18" YourAdditonalCostType="MULTIPLE" PromotionPrice="0.0" Currency="USD" />
            <Price Duration="3" DurationType="YEAR" Price="10.78" PricingType="MULTIPLE" AdditionalCost="0.18" RegularPrice="10.78" RegularPriceType="MULTIPLE" RegularAdditionalCost="0.18" RegularAdditionalCostType="MULTIPLE" YourPrice="10.78" YourPriceType="MULTIPLE" YourAdditonalCost="0.18" YourAdditonalCostType="MULTIPLE" PromotionPrice="0.0" Currency="USD" />
            <Price Duration="4" DurationType="YEAR" Price="10.68" PricingType="MULTIPLE" AdditionalCost="0.18" RegularPrice="10.68" RegularPriceType="MULTIPLE" RegularAdditionalCost="0.18" RegularAdditionalCostType="MULTIPLE" YourPrice="10.68" YourPriceType="MULTIPLE" YourAdditonalCost="0.18" YourAdditonalCostType="MULTIPLE" PromotionPrice="0.0" Currency="USD" />
            <Price Duration="5" DurationType="YEAR" Price="10.58" PricingType="MULTIPLE" AdditionalCost="0.18" RegularPrice="10.58" RegularPriceType="MULTIPLE" RegularAdditionalCost="0.18" RegularAdditionalCostType="MULTIPLE" YourPrice="10.58" YourPriceType="MULTIPLE" YourAdditonalCost="0.18" YourAdditonalCostType="MULTIPLE" PromotionPrice="0.0" Currency="USD" />
            <Price Duration="6" DurationType="YEAR" Price="10.58" PricingType="MULTIPLE" AdditionalCost="0.18" RegularPrice="10.58" RegularPriceType="MULTIPLE" RegularAdditionalCost="0.18" RegularAdditionalCostType="MULTIPLE" YourPrice="10.58" YourPriceType="MULTIPLE" YourAdditonalCost="0.18" YourAdditonalCostType="MULTIPLE" PromotionPrice="0.0" Currency="USD" />
            <Price Duration="7" DurationType="YEAR" Price="10.58" PricingType="MULTIPLE" AdditionalCost="0.18" RegularPrice="10.58" RegularPriceType="MULTIPLE" RegularAdditionalCost="0.18" RegularAdditionalCostType="MULTIPLE" YourPrice="10.58" YourPriceType="MULTIPLE" YourAdditonalCost="0.18" YourAdditonalCostType="MULTIPLE" PromotionPrice="0.0" Currency="USD" />
            <Price Duration="8" DurationType="YEAR" Price="10.58" PricingType="MULTIPLE" AdditionalCost="0.18" RegularPrice="10.58" RegularPriceType="MULTIPLE" RegularAdditionalCost="0.18" RegularAdditionalCostType="MULTIPLE" YourPrice="10.58" YourPriceType="MULTIPLE" YourAdditonalCost="0.18" YourAdditonalCostType="MULTIPLE" PromotionPrice="0.0" Currency="USD" />
            <Price Duration="9" DurationType="YEAR" Price="10.58" PricingType="MULTIPLE" AdditionalCost="0.18" RegularPrice="10.58" RegularPriceType="MULTIPLE" RegularAdditionalCost="0.18" RegularAdditionalCostType="MULTIPLE" YourPrice="10.58" YourPriceType="MULTIPLE" YourAdditonalCost="0.18" YourAdditonalCostType="MULTIPLE" PromotionPrice="0.0" Currency="USD" />
            <Price Duration="10" DurationType="YEAR" Price="10.58" PricingType="MULTIPLE" AdditionalCost="0.18" RegularPrice="10.58" RegularPriceType="MULTIPLE" RegularAdditionalCost="0.18" RegularAdditionalCostType="MULTIPLE" YourPrice="10.58" YourPriceType="MULTIPLE" YourAdditonalCost="0.18" YourAdditonalCostType="MULTIPLE" PromotionPrice="0.0" Currency="USD" />
          </Product>
        </ProductCategory>
      </ProductType>
    </UserGetPricingResult>
  </CommandResponse>
  <Server>PHX01APIEXT02</Server>
  <GMTTimeDifference>--4:00</GMTTimeDifference>
  <ExecutionTime>0.063</ExecutionTime>
</ApiResponse>

1 个答案:

答案 0 :(得分:0)

根据通过评论中的链接共享的更新XML,可以使用以下解决方案实现html输出。

<Price>元素的属性列表对于不同的<Product>是不同的。在输出中,属性值需要显示在相应列的下方。

为属性名称

定义了一个键
<xsl:key name="key-attr-name" match="res:Price/@*" use="name(.)"/>

该密钥用于在生成标题行时获取唯一名称。

<tr>
    <th>ProductCategory</th>
    <th>Product</th>
    <xsl:for-each select="(//res:Price/@*)[generate-id(.) = generate-id(key('key-attr-name', name(.))[1])]">
        <th><xsl:value-of select="name()" /></th>
    </xsl:for-each>
</tr>

类似地,该密钥将用于将属性的值填充为表中的数据。

<xsl:for-each select="//res:Price">
    <tr>
        <td><xsl:value-of select="ancestor::res:ProductCategory/@Name" /></td>
        <td><xsl:value-of select="ancestor::res:Product/@Name" /></td>
        <xsl:variable name="curr-price" select="."/>
        <xsl:for-each select="(//res:Price/@*)[generate-id(.) = generate-id(key('key-attr-name', name(.))[1])]">
            <td>
                <xsl:value-of select="$curr-price/@*[name(.) = name(current())]" />
            </td>
        </xsl:for-each> 
    </tr>
</xsl:for-each>

对于您的评论它生成了一个HTML文件,但它是空的,没有行。,原因可能是XSLT中没有声明名称空间http://api.namecheap.com/xml.response。输入XML具有与之关联的命名空间,需要在XSLT中声明,并且应使用前缀(别名)viz访问属于命名空间的元素。 res:Price。下面是如何声明命名空间并省略输出中的前缀。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:res="http://api.namecheap.com/xml.response" exclude-result-prefixes="res">

完整的XSLT和输出如下

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:res="http://api.namecheap.com/xml.response" exclude-result-prefixes="res">
    <xsl:output method="html" indent="yes"/>
    <xsl:strip-space elements="*" />

    <xsl:key name="key-attr-name" match="res:Price/@*" use="name(.)"/>

    <xsl:template match="/">
        <html>
            <body>
                <table border="1" cellspacing="0" cellpadding="5">
                    <tr>
                        <th>ProductCategory</th>
                        <th>Product</th>
                        <xsl:for-each select="(//res:Price/@*)[generate-id(.) = generate-id(key('key-attr-name', name(.))[1])]">
                            <th><xsl:value-of select="name()" /></th>
                        </xsl:for-each>
                    </tr>
                    <xsl:for-each select="//res:Price">
                        <tr>
                            <td><xsl:value-of select="ancestor::res:ProductCategory/@Name" /></td>
                            <td><xsl:value-of select="ancestor::res:Product/@Name" /></td>
                            <xsl:variable name="curr-price" select="."/>
                            <xsl:for-each select="(//res:Price/@*)[generate-id(.) = generate-id(key('key-attr-name', name(.))[1])]">
                                <td>
                                    <xsl:value-of select="$curr-price/@*[name(.) = name(current())]" />
                                </td>
                            </xsl:for-each> 
                        </tr>
                    </xsl:for-each>
                </table>
            </body>
        </html>
    </xsl:template>
</xsl:stylesheet>

输出

HTML Output