【问题标题】:xslt transformation from xhtml to custom xml从 xhtml 到自定义 xml 的 xslt 转换
【发布时间】:2010-01-29 21:23:06
【问题描述】:

对于自定义应用程序,我需要将 xhtml 转换为(自定义)xml。经过一些实验后,我决定尝试一下 php5 的 XSLT 功能,但到目前为止,我无法将嵌套的 p 标签转换为它们的等效 xml。

基本上我们有这样的代码:

<p>Some text</p>
<ol>
   <li><p>Some more text</p></li>
   ..
</ol>

这需要转化为:

<par>Some text</par>
<list>
  <li><par>Some more text</par></li>
  ..
</list>

真正的问题是:我需要包含内联标签,所以 xsl:value-of 不是选项,而是我使用 xsl:copy-of。到目前为止,我有 ol|ul 和 p 的模板,结果是这样的:

<par>Some text</par>
<list>
  <li><p>Some more text</p></li>
  ..
</list>

有人提示如何通过使用更复杂的 xslt 来实现我真正想要的吗?

【问题讨论】:

    标签: php xml xslt


    【解决方案1】:

    给你...

    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
        <xsl:output method="xml" indent="yes"/>
        <!-- ============================================== -->
        <xsl:template match="/">
            <xsl:apply-templates/>
        </xsl:template>
        <!-- ============================================== -->
        <xsl:template match="p">
            <xsl:element name="par">
                <xsl:apply-templates/>
            </xsl:element>
        </xsl:template>
        <!-- ============================================== -->
        <xsl:template match="ol">
            <xsl:element name="list">
                <xsl:apply-templates/>
            </xsl:element>
        </xsl:template>
        <!-- ============================================== -->
        <xsl:template match="li">
            <xsl:element name="li">
                <xsl:apply-templates/>
            </xsl:element>
        </xsl:template>
        <!-- ============================================== -->
    </xsl:stylesheet>
    

    【讨论】:

    • 非常感谢!这确实让我更进一步,但是似乎内联元素以这种方式丢失了?
    • 你不能同时拥有它。如果您要求提供副本,则不会进行进一步处理。您应该做的是创建一个复制元素名称的默认模板,并继续处理,并为您正在更改的元素覆盖该模板。
    • “内联元素”是什么意思?
    • 你的意思是说如果“p”标签嵌入到“li”标签中,就不会被转换成“par”?
    • 我的意思是这样的:

      粗体文本更多的文本

      然而,简单地为所有子元素和内联元素添加更多模板,似乎是一个很好的解决方案: )
    【解决方案2】:

    如果您从identity transform 开始,将具有一个名称的元素转换为另一个名称的元素的一般模式是这样的:

    <xsl:template match="old_name">
       <new_name>
          <xsl:apply-templates select="node()|@*"/>
       </new_name>
    </xsl:template>
    

    注意两点:

    1. 通常,除非您确定要转换的元素没有属性(或者您主动打算去除属性),否则应使用所示的select 属性;不要只使用&lt;xsl:apply-templates/&gt;。属性不是子节点,因此应用没有select 属性的模板不会将模板应用到它们。

    2. 除非您真的很喜欢打字,否则几乎没有理由使用&lt;xsl:element&gt;。例外情况是您以编程方式生成输出元素的名称。

    实际上,如果您想获得所有花哨的东西,您可以这样做:

    <xsl:template match="*">
       <xsl:variable name="new_name">
          <xsl:when test="name()='p'>par</xsl:when>
          <xsl:when test="name()='ol'>list</xsl:when>
          <xsl:when test="name()='li'>item</xsl:when>
          <xsl:otherwise><xsl:value-of select="name()"/></xsl:otherwise>
       </xsl:variable>
       <xsl:element name="{$new_name}">
          <xsl:apply-templates select="@*|node()"/>
       </xsl:element>
    </xsl:template>
    

    【讨论】:

    • +1(如果可以的话,还有更多+1) - 请注意test="name()='p' 将不起作用除非 XSL 文档与 XHTML 输入位于相同的默认命名空间中.可以改用local-name(),但使用前缀声明XHMTL 命名空间并更改为test="name()='xhtml:p' 是更简洁的解决方案。
    【解决方案3】:

    您可以使用嵌套的&lt;xsl:element&gt; 标签来输出您建议的内联标签。

    类似:

    <xsl:element name="li">
      <xsl:element name="p">
       some text
      </xsl:element>
    </xsl:element>
    

    【讨论】:

    • 你能举个例子吗?我是否需要将其放入模板中,结果是静态的还是动态的(例如我可以“回收”任意内容和内联标签还是只是输出一组固定的元素和内容)?
    猜你喜欢
    • 2011-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多