【问题标题】:Transforming XML data to HTML using XSL and Php: only printing xml tags without any formatting使用 XSL 和 Php 将 XML 数据转换为 HTML:仅打印 xml 标记而不进行任何格式化
【发布时间】:2010-12-02 13:30:25
【问题描述】:

我必须将我的 xml 输出转换为 html。我正在关注link text 的教程,我的代码在一行中输出 xml 标记,没有任何带有文本值的格式。我希望输出为 HTML 无序列表,遵循 xml 文件输出中父子级的层次结构。

这是页面输出:

message msg 1message msg 1-1message msg 1-2message msg 1-2-1message msg 1-2-2message 
msg 1-2-2-1message msg 1-2-2-1-1message msg 1-2-2-1-2 

&这里是页面来源:

<html:ul xmlns:html="http://www.w3.org/1999/xhtml"><html:li>message msg 1</html:li>
<html:ul><html:li>message msg 1-1</html:li><html:li>message msg 1-2</html:li><html:ul>
<html:li>message msg 1-2-1</html:li><html:li>message msg 1-2-2</html:li><html:ul>
<html:li>message msg 1-2-2-1</html:li><html:ul><html:li>message msg 1-2-2-1-1</html:li>
<html:li>message msg 1-2-2-1-2</html:li></html:ul></html:ul></html:ul></html:ul></html:ul>

这是我的代码

php file:

<?php
# LOAD XML FILE
$XML = new DOMDocument();
$XML->load('messages.xml');

# START XSLT
$xslt = new XSLTProcessor();
$XSL = new DOMDocument();
$XSL->load('msg.xsl');
$xslt->importStylesheet( $XSL );
print $xslt->transformToXML( $XML );
?>

msg.xsl:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:html="http://www.w3.org/1999/xhtml">
  <xsl:output omit-xml-declaration="yes" />

  <xsl:template match="messages">
    <html:ul>
      <xsl:apply-templates select="message" />
    </html:ul>
  </xsl:template>

  <xsl:template match="message[message]">
    <html:li>message <xsl:value-of select="@msg_id" /></html:li>
    <html:ul>
      <xsl:apply-templates select="message" />
    </html:ul>
  </xsl:template>

  <xsl:template match="message">
    <html:li>message <xsl:value-of select="@msg_id" /></html:li>
    <xsl:apply-templates select="message" />
  </xsl:template>
</xsl:stylesheet>

messages.xml

<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="msg.xsl"?><messages>
    <message msg_id="1" emp_msg="msg 1" parent_msg_id="" parent_msg="" depth="0">
        <message msg_id="2" emp_msg="msg 1-1" parent_msg_id="1" parent_msg="msg 1" depth="1"/>
        <message msg_id="3" emp_msg="msg 1-2" parent_msg_id="1" parent_msg="msg 1" depth="1">
            <message msg_id="4" emp_msg="msg 1-2-1" parent_msg_id="3" parent_msg="msg 1-2" depth="2"/>
            <message msg_id="5" emp_msg="msg 1-2-2" parent_msg_id="3" parent_msg="msg 1-2" depth="2">
                <message msg_id="6" emp_msg="msg 1-2-2-1" parent_msg_id="5" parent_msg="msg 1-2-2" depth="3">
                    <message msg_id="7" emp_msg="msg 1-2-2-1-1" parent_msg_id="6" parent_msg="msg 1-2-2-1" depth="4"/>
                    <message msg_id="8" emp_msg="msg 1-2-2-1-2" parent_msg_id="6" parent_msg="msg 1-2-2-1" depth="4"/>
                </message>
            </message>
        </message>
    </message>
</messages>

【问题讨论】:

  • XML 文件是否因为剪切和粘贴错误而无效,还是您要转换的内容? - 最后一行“”应该是“”
  • 您的输出是什么样的,您希望它是什么样的?
  • @Chris Bentley,这只是剪切和粘贴错误。我修复了错误,这是由于使用“loadXML”而不是“load”来加载 xml 文档。虽然它没有显示结果,只是输出标签。我更新了我的问题。
  • 这不是我在这里得到的输出。你看网页源码了吗?
  • @Ignacio Vazquez-Abrams,它显示所有带有数字的 xml 标签。数字可能作为它的一部分从 xml 输出中获得。我将输出添加到 OP。实际上,我希望在 xml 文件输出中按照父子的层次结构将输出作为 HTML 无序列表。 & 它应该包含“msg_id”和“emp_msg”的值。

标签: php html xml xslt


【解决方案1】:

您的样式表输出的不是 HTML,而是一个 XHTML 片段,并且您需要以某种方式(使用限定名称)将其作为应用程序/xml 提供给浏览器(如 Mozilla、Opera、Safari、IE 9,但不是 IE 6-8) 理解该内容类型。

所以请确保你做类似的事情

  header('Content-Type: application/xml');

在将内容发送到浏览器之前。或者从结果元素中删除任何 XHTML 命名空间和任何前缀,然后 XSLT 样式表输出一个 HTML 片段,更多的浏览器可以解析和理解为 text/html 并根据需要呈现它。

【讨论】:

  • header 是一个 PHP 函数 php.net/manual/en/function.header.php 所以假设您使用 PHP,您需要在将任何内容发送到浏览器之前在您的 PHP 代码中调用 sbown 函数,因此请确保将其放在打印之前声明。
  • @XCeptable:您可以通过删除xmlns:html 属性并删除每个元素前面的html: 来摆脱html 命名空间。确保单独保留 xsl 命名空间,因为它是使 XSLT 工作所必需的。
  • 你太棒了 :),感谢千千万万次
  • @Ignacio Vazquez-Abrams,比 X 千倍 ignacio,你的 xsl 工作得非常好 :) 但仍有一些工作要做。因为我通过在本地保存它来使用这个xml,但是在应用程序中,它是由php代码动态生成的,所以我该怎么做。我是否应该用在 xml 中生成结果集的代码替换“loadXML”部分,在 xml 中获取该输出并使用?或者我应该为此提出一个新问题吗?
【解决方案2】:

要成为跨浏览器,我会使用这个样式表:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output omit-xml-declaration="yes"
                doctype-public="-//W3C//DTD HTML 4.0//EN"
                doctype-system="http://www.w3.org/TR/html4/strict.dtd"/>
    <xsl:template match="messages">
        <html>
            <body>
                <xsl:apply-templates select="*[1]"/>
            </body>
        </html>
    </xsl:template>
    <xsl:template match="message[1]">
        <ul>
            <xsl:call-template name="makeListItem"/>
        </ul>
    </xsl:template>
    <xsl:template match="message" name="makeListItem">
        <li>
            <xsl:value-of select="concat('message ',@msg_id)" />
            <xsl:apply-templates select="*[1]"/>
        </li>
        <xsl:apply-templates select="following-sibling::*[1]"/>
    </xsl:template>
</xsl:stylesheet>

输出:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<body>
<ul>
 <li>message 1
  <ul>
   <li>message 2</li>
   <li>message 3
    <ul>
     <li>message 4</li>
     <li>message 5
      <ul>
       <li>message 6
        <ul>
         <li>message 7</li>
         <li>message 8</li>
        </ul>
       </li>
      </ul>
     </li>
    </ul>
   </li>
  </ul>
 </li>
</ul>
</body>
</html>

渲染为:

  • 消息 1
    • 消息 2
    • 消息 3
      • 消息 4
      • 消息 5
        • 消息 6
          • 消息 7
          • 消息 8

注意:HTML DOCTYPE,没有命名空间。还有其他通过细粒度遍历进行层次结构处理的方法。

【讨论】:

  • @Alejandro,我用过这个,但它打印简单的 xml,没有任何格式
  • @XCeptable:很奇怪!我已经使用您的确切 PHP 代码、您的确切输入示例和我的样式表进行了测试。
  • @XCeptable:那是因为您没有使用所讨论的确切 PHP 代码:您已按照 @Martin Honnen 的建议添加了 Content Type 标头,或者您已在 .htaccess 中添加了此 Content Type文件,或任何后处理器。该消息来自浏览器,意思很简单:“这是一个没有 CSS 和 XSLT 样式表的 XML 文档,所以我(浏览器)将使用我自己的样式表”
  • @Alejandro,你说得对,我无话可说,因为它突然间让一切正常工作,因为你不使用任何类型的标题。再次感谢成千上万
  • @Alejandro, 如果我想打印一个标签,说 msg_id 只在 root 而不是在 child那么该怎么做呢?
猜你喜欢
  • 1970-01-01
  • 2011-12-25
  • 1970-01-01
  • 2012-02-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多