通过 xsl 将 XML 转换为 HTML 会导致以下问题:xsl 中的关键函数未提供所需的输出

Posted

技术标签:

【中文标题】通过 xsl 将 XML 转换为 HTML 会导致以下问题:xsl 中的关键函数未提供所需的输出【英文标题】:turning XML into HTML via xsl causing following issue: key function in xsl does not deliver the desired output 【发布时间】:2021-06-30 19:12:18 【问题描述】:

我正在测试一个 XSL 代码,但它没有提供所需的输出。

XML

<data>
  <products>
    <product>
      <id>1</id>
      <description>Tea Leaves - Oolong</description>
      <price>$4.57</price>
      <lead>1</lead>
    </product>
    <product>
      <id>2</id>
      <description>Beans - Navy, Dry</description>
      <price>$11.96</price>
      <lead>1</lead>
    </product>
  </products>
  <customers>
    <customer>
      <id>1</id>
      <name>Alexis Templar</name>
    </customer>
    <customer>
      <id>2</id>
      <name>Valentin McGlue</name>
    </customer>
    <customer>
      <id>3</id>
      <name>Bjorn Saxelby</name>
    </customer>
  </customers>
</data>

XSL

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:key name="keyToProduct" match="product" use="lead"/>
  <xsl:template match="/">
    <html>
      <head>
        <title>Produktübersicht</title>
        <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta2/dist/css/bootstrap.min.css" 
          rel="stylesheet" integrity="sha384-BmbxuPwQa2lc/FVzBcNJ7UAyJxM6wuqIj61tLrc4wSX0szH/Ev+nYRRuWlolflfl" 
          crossorigin="anonymous"/>
        <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta2/dist/js/bootstrap.bundle.min.js" 
          integrity="sha384-b5kHyXgcpbZJO/tY9Ul7kGkf1S0CWuKcCD38l8YkeH8z8QjE0GmW1gYU5S9FOnJ0" 
          crossorigin="anonymous"></script>
      </head>
      <body style="background-color:beige;">
        <div class="container">
          <h1 style="background-color:beige; color:blue;">Produktauswahl der Kunden</h1>
          <h3> Für jeden Kunden wird hier eine Gesamtauflistung aller eingekaufter Produkte veranschaulicht. 
            Ein Kunde kann sowohl kein Produkt oder aber sehr viele gekauft haben.</h3>
          <xsl:for-each select="data/customers/customer">
            <div class="card my-2">
              <div class="card-header">
                <xsl:value-of select="name"/>
              </div>
              <div calss="card-body">
                <button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs- 
                  target="#exampleModalid">
                  <p>Produktübersicht</p>
                </button>
                <div class="modal fade" id="exampleModalid" tabindex="-1" aria-labelledby="exampleModalLabel" aria- 
                  hidden="true">
                  <div class="modal-dialog">
                    <div class="modal-content">
                      <div class="modal-header">
                        <h5 class="modal-title" id="exampleModalLabel">Produktübersicht</h5>
                        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
                      </div>
                      <div class="modal-body">
                        <xsl:for-each select="key('keyToProduct',id)">
                          <xsl:if test="key('keyToProduct',id)/lead &gt; 0">
                            <ul class="list-group">
                              <li class="list-group-item">
                                <p>Beschreibung:
                                  <xsl:value-of select="key('keyToProduct', id)/description"/></p>
                              </li>
                              <li class="list-group-item">
                                <p>Preis:
                                  <xsl:value-of select="key('keyToProduct', id)/price"/></p>
                              </li>
                              <li class="list-group-item">
                                <p>ID:
                                  <xsl:value-of select="key('keyToProduct', id)/id"/></p>
                              </li>
                            </ul>
                          </xsl:if>
                        </xsl:for-each>
                      </div>
                      <div class="modal-footer">
                        <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Schliessen</button>
                      </div>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </xsl:for-each>
        </div>
      </body>
    </html>
  </xsl:template>
</xsl:stylesheet>>

期望的输出: ID 为 1 的客户应该同时获得这两种产品,因为他们都使用数字 1 作为线索。但是,为什么在我将文件转换为 html 后,输出仅显示一种产品 客户说。

【问题讨论】:

请发布minimal reproducible example,而不是脱离上下文的sn-ps(而不是60多行代码)。还包括预期结果。 XML: 1茶叶 -乌龙茶$4.57202Beans - Navy, Dry$11.96701Alexis Templar2Valentin McGlue 嗨,Davud,欢迎来到 Stack Overflow。请不要在评论中发布那么多代码。您可以编辑自己的问题以使用请求的内容对其进行更新。但是,您似乎通过key('keyToProduct', id) 解析客户的产品。您的数据中缺少客户和产品的关系。请通过编辑您的问题向我们展示。 嘿,非常感谢您的提示...我刚刚编辑了我的问题,希望现在有意义.. 第一次使用堆栈溢出,对此感到抱歉 &lt;xsl:for-each select="key('keyToProduct',id)"&gt; 的上下文是什么? 【参考方案1】:

考虑以下两条指令:

<xsl:for-each select="key('keyToProduct',id)">
  <xsl:if test="key('keyToProduct',id)/lead &gt; 0">

我强烈希望您期望key('keyToProduct',id) 上的两个调用返回相同的结果。但是外部表达式改变了上下文,所以外部表达式中的child::id 与内部表达式中的child::id 不同。用“.”替换内部调用。同样,key() 上的其他电话。

【讨论】:

以上是关于通过 xsl 将 XML 转换为 HTML 会导致以下问题:xsl 中的关键函数未提供所需的输出的主要内容,如果未能解决你的问题,请参考以下文章

使用 XSL 将 json 转换为 XML

XSLT

如何使用 xsl 拆分 html 文件?

使用从 xml 到 html 的 xsl 转换来维护空格和换行符

如何使用 XSL 将 XML 转换为 CSV

如何使用 XSL 将 liquibase XML 转换为 CSV