【问题标题】:Transform XML using XSL使用 XSL 转换 XML
【发布时间】:2012-08-12 13:52:54
【问题描述】:

我正在用一个简单的 XSL 格式化一个 xml 文件,当容器标签中没有其他数据时它可以正常工作,但如果标签中有数据则不显示任何数据。

XML 是这样的就可以了

<Result>
 <primaryTopic> 
  <CompanyName>ZENITH PRINT (UK) LIMITED</CompanyName>
  <RegAddress>
    <AddressLine1>ZENITH HOUSE</AddressLine1>
    <AddressLine2>MOY ROAD INDUSTRIAL ESTATE</AddressLine2>
    <PostTown>TAFFS WELL</PostTown>
    <County>CARDIFF</County>
    <Postcode>CF15 7QR</Postcode>
  </RegAddress>

当标签中有这样的 url 数据时,它会失败

<Result xmlns="http://#####.uk/terms/xxx">
 <primaryTopic> 
  <CompanyName>ZENITH PRINT (UK) LIMITED</CompanyName>
  <RegAddress href="http://#####.uk/doc/company/02050399#RegAddress">
    <AddressLine1>ZENITH HOUSE</AddressLine1>
    <AddressLine2>MOY ROAD INDUSTRIAL ESTATE</AddressLine2>
    <PostTown>TAFFS WELL</PostTown>
    <County>CARDIFF</County>
    <Postcode>CF15 7QR</Postcode>
  </RegAddress>

我正在使用的 XSL

<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- Edited by XMLSpy® -->
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
  <html>
  <body>
    <h2><xsl:value-of select="Result/primaryTopic/CompanyName"/></h2>
    <table border="1">
      <tr>
        <td>Company Name</td>
        <td><xsl:value-of select="Result/primaryTopic/CompanyName"/></td>
        <td>Address</td>
        <td><xsl:value-of select="Result/primaryTopic/RegAddress/AddressLine1"/></td>
      </tr>
    </table>
  </body>
  </html>
</xsl:template>
</xsl:stylesheet>

【问题讨论】:

  • 失败消息是什么?或者你期待什么你看到了什么
  • 无法重现,两个 XML 在这里给出相同的输出。
  • 网址中的“#####”实际上是“#####”吗?还是您已更改为匿名的那些字符?注意 XML 属性中不允许使用字符
  • 没有错误信息。它只显示 CompanyName 数据,没有其他内容。我期待它在那之后显示来自 ADDRESSLINE1 (ZENITH HOUSE) 的数据。
  • ####.co.uk 只是为了隐藏网址。它在 XML 中的格式正确

标签: xml xslt


【解决方案1】:

问题在于,对于第二个示例,已指定默认命名空间,因此 XML 中的所有元素都将成为该命名空间的一部分

<Result xmlns="http://#####.uk/terms/xxx">

但是,您的 XSLT 正在寻找没有命名空间的元素,因此它不会匹配 XML 中确实有命名空间的元素。

解决方案是在匹配元素时确保命名空间是 XSLT 的一部分

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xxx="http://#####.uk/terms/xxx" exclude-result-prefixes="xxx">
   <xsl:template match="/">
      <html>
         <body>
            <h2>
               <xsl:value-of select="xxx:Result/xxx:primaryTopic/xxx:CompanyName"/>
            </h2>
            <table border="1">
               <tr>
                  <td>Company Name</td>
                  <td>
                     <xsl:value-of select="xxx:Result/xxx:primaryTopic/xxx:CompanyName"/>
                  </td>
                  <td>Address</td>
                  <td>
                     <xsl:value-of select="xxx:Result/xxx:primaryTopic/xxx:RegAddress/xxx:AddressLine1"/>
                  </td>
               </tr>
            </table>
         </body>
      </html>
   </xsl:template>
</xsl:stylesheet>

当然,这只适用于您的第二个 XML 示例,而不是第一个。如果您想要一个适用于这两个示例的 XSLT,您可以执行类似的操作来检查元素名称,而不考虑名称空间。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:template match="/*/*[local-name()='primaryTopic']">
      <html>
         <body>
            <h2>
               <xsl:value-of select="*[local-name() = 'CompanyName']"/>
            </h2>
            <table border="1">
               <tr>
                  <td>Company Name</td>
                  <td>
                     <xsl:value-of select="*[local-name() = 'CompanyName']"/>
                  </td>
                  <td>Address</td>
                  <td>
                     <xsl:value-of select="*[local-name() = 'RegAddress']/*[local-name() = 'AddressLine1']"/>
                  </td>
               </tr>
            </table>
         </body>
      </html>
   </xsl:template>
</xsl:stylesheet>

这应该为第一个和第二个 XML 样本提供相同的输出。

【讨论】:

  • 谢谢蒂姆。这正是我所需要的。
【解决方案2】:

您的 XSL 对这两种 XML 都适用。一定有其他事情出错了。向 XML 节点添加属性不得影响转换。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-02-01
    • 2016-02-12
    • 1970-01-01
    • 2011-12-31
    • 2013-09-07
    • 2017-04-16
    • 1970-01-01
    相关资源
    最近更新 更多