【问题标题】:How to get multiple views (html) using XSLT on 1 XML file如何在 1 个 XML 文件上使用 XSLT 获取多个视图 (html)
【发布时间】:2013-01-16 14:52:14
【问题描述】:

我有 1 个包含我需要的所有数据的大型 XML 文件。

我需要的是这样的: 1 页 = 概述。在此页面上显示了一个表格。每行都以指向详细信息页面的超链接开头。

我正在寻找一种仅使用 XML、XSLT 和 HTML 的方法。没有服务器端处理。

有什么方法可以实现吗?

现在 XML 有 XSLT 用于在标题中指定的概述:

<?xml-stylesheet type="text/xsl" href="overview.xslt"?>

如果我不能处理多个 XSLT 文件,有没有办法从 XSLT 中的 url 读取查询字符串?

【问题讨论】:

  • 您生成的 html 概览页面应该有 href 到详细信息页面,其中将包含
  • 我只使用 XML + XSLT。没有生成实际的 html 文件
  • 生成的 HTML 标记应该有一个指向引用 details.xslt 转换的 XML 文件的超链接。
  • 我只有 1 个包含所有所需数据的 XML 文件
  • 如果无法动态提供 XML 并插入所需的 &lt;?xsl-stylesheet ?&gt;,也许下一个最佳选择是让 XSLT 输出所有内容的所有 HTML,其中大部分最初是隐藏的,然后根据需要使用 JavaScript 显示或隐藏它。当然,根据 XML 文件的大小,这可能会产生大量的 HTML,因此实际的数量会有限制。

标签: html xml xslt


【解决方案1】:

我看到两个选项:

  1. 让 XSLT 创建一个大 HTML 并隐藏除您要显示的部分之外的所有部分。
  2. 使用 JavaScript 启动不同的转换,将当前 HTML 的正文替换为转换返回的 HTML 正文。您可以使用一个样式表,根据需要为每个转换提供的 &lt;xsl:parameter&gt; 的值采用不同的路径,或者使用不同的样式表。

假设您有以下 XML(我们称之为 text.xml):

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="test.xsl"?>
<myXml>
  <chapter id="c1">
    <heading>Heading 1</heading>
    <content>This is text of chapter one.</content>
  </chapter>
  <chapter id="c2">
    <heading>Heading 2</heading>
    <content>This is text of chapter two.</content>
  </chapter>
</myXml>

那么,对于建议 1,您可以这样做:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output method="html"/>

  <xsl:template match="/">
    <html>
      <head>
        <title></title>
        <script type="text/javascript">
          function showView(id) {
            document.getElementById("dynamicStyle").innerHTML = "#" + id + "{display:inline}";
          }
        </script>
        <style type="text/css">
          .view {display:none};
        </style>
        <style type="text/css" id="dynamicStyle">
          #overview{display:inline}
        </style>
      </head>
      <body>
        <div class="view overview" id="overview">
          <h1>Overview</h1>
          <xsl:apply-templates select="myXml/chapter" mode="overview"/>
        </div>
        <xsl:apply-templates select="myXml/chapter" mode="detail"/>
      </body>
    </html>
  </xsl:template>

  <xsl:template match="chapter" mode="overview">
    <div><a href="javascript:showView('{@id}')"><xsl:value-of select="heading"/></a></div>
  </xsl:template>

  <xsl:template match="chapter" mode="detail">
    <div class="view detail" id="{@id}">
      <div><a href="javascript:showView('overview')">Back to overview</a></div>
      <xsl:apply-templates mode="detail"/>
    </div>
  </xsl:template>

  <xsl:template match="heading" mode="detail">
    <h1><xsl:value-of select="."/></h1>
  </xsl:template>

  <xsl:template match="content" mode="detail">
    <div><xsl:value-of select="."/></div>
  </xsl:template>
</xsl:stylesheet>

关键是为每个视图创建单独的 div,并通过让 JavaScript 更改 CSS 在它们之间切换。

方法 2 可能如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output method="html"/>

  <xsl:param name="view" select="'overview'"/>

  <xsl:template match="/">
    <html>
      <head>
        <title></title>
        <script type="text/javascript">
          function showView(id) {
            document.documentElement.replaceChild(transform(id).body, document.body);
          }
          function loadXML(fileName,mime) {
            var xmlHttpRequest = new XMLHttpRequest();
            xmlHttpRequest.open("GET",fileName,false);
            if(mime) xmlHttpRequest.overrideMimeType(mime);
            xmlHttpRequest.send("");
            return xmlHttpRequest.responseXML;
          }
          function transform(view) {
            var xsltProcessor = new XSLTProcessor();
            xsltProcessor.importStylesheet(loadXML('test.xsl','application/xslt+xml'));
            xsltProcessor.setParameter(null,'view',view);
            return xsltProcessor.transformToDocument(loadXML('test.xml'),document);
          }
        </script>
      </head>
      <body>
        <xsl:choose>
          <xsl:when test="$view = 'overview'">
            <div>
              <h1>Overview</h1>
              <xsl:apply-templates select="myXml/chapter" mode="overview"/>
            </div>
          </xsl:when>
          <xsl:otherwise>
            <xsl:apply-templates select="myXml/chapter[@id = $view]" mode="detail"/>
          </xsl:otherwise>
        </xsl:choose>
      </body>
    </html>
  </xsl:template>

  <xsl:template match="chapter" mode="overview">
    <div><a href="javascript:showView('{@id}')"><xsl:value-of select="heading"/></a></div>
  </xsl:template>

  <xsl:template match="chapter" mode="detail">
    <div>
      <div><a href="javascript:showView('overview')">Back to overview</a></div>
      <xsl:apply-templates mode="detail"/>
    </div>
  </xsl:template>

  <xsl:template match="heading" mode="detail">
    <h1><xsl:value-of select="."/></h1>
  </xsl:template>

  <xsl:template match="content" mode="detail">
    <div><xsl:value-of select="."/></div>
  </xsl:template>
</xsl:stylesheet>

这里的关键是使用 JavaScript 加载样式表和 XML,并使用 JavaScript 对象XSLTProcessor 进行转换,然后替换文档的正文。在此示例中,我使用了一个具有不同参数的样式表,但您也可以加载不同的样式表。您必须相应地调整 transform() 函数,将 test.xsl 替换为需要以某种方式提供的变量。

【讨论】:

  • 感谢您的详细回答。现在的结论是我必须生成所有单独的 html 文件。 2 个原因: 1. 随着时间的推移,生成的 html 文件会变得太大。 2. iphone网络浏览器似乎不支持浏览器中的XML + XSLT(至少我无法让它工作)。
  • 你确定是 iPhone 吗?我手头没有任何 iOS 设备,但不久前我在 iPad 上成功运行了一个应用程序,该应用程序使用了我的方法 2 中的一些东西。
  • 方法 2 可能有效,无效的是其中包含 Xslt 引用的简单 xml。刚刚在 Safari 中的 iPad 上对其进行了测试,它确实可以工作。奇怪!
猜你喜欢
  • 2023-02-23
  • 1970-01-01
  • 2012-08-23
  • 1970-01-01
  • 1970-01-01
  • 2013-08-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多