使用XSLT进行HTML到XML转换的嵌套<ul>标记</ul>

时间:2013-04-26 15:48:20

标签: html xslt xpath xslt-1.0

我有这些嵌套的<ul>标签。我想要做的是将其中一些转换为<para>标签。

所以我有这个代码:

<xsl:template match="ul">
<para>
<xsl:apply-templates select="*|@*|text()"/>
</para>
</xsl:template>

我的问题是,当我嵌套<ul>标记时,它会为所有标记创建<para> - 所以如果我有<ul><ul>,它将创建<para><para>。如果<para>嵌套在另一个<ul>或任何其他标记中,或者什么都没有,我如何才能创建一个<ul>

示例XML输入:

是的 - 所以我有<ul>A. The definition of "Panoply" is:</ul>然后是<ul><ul>A Large assortment</ul></ul>。我想将<ul>加倍<blockquote>,但它已经从另一个模板中取出<para>而我正在使用的dtd不允许在段落中使用块引用

其他编辑

基本上我要做的是删除两个标签而不是一个。如果我写

<xsl:template match="ul/ul">
<xsl:apply-templates select="*|@*|text()"/>
</xsl:template>

它只会移除第二个<ul>,如何删除它们?

上面的示例输入的预期输出将是

<para>A. The definition of "Panoply" is:</para>
<blockquote>A Large assortment</blockquote>

而不是

<para>A. The definition of "Panoply" is:</para>
<para><para>A Large assortment</para></para>

3 个答案:

答案 0 :(得分:0)

以下内容应该有效:

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

<xsl:template match="ul[ul]">
    <blockquote>
        <xsl:apply-templates select="@*|ul/node()"/>
    </blockquote>
</xsl:template>

第二个模板仅匹配具有ul子项的ul,并仅处理这些子项的内容。第一个模板匹配所有其他ul个节点。

答案 1 :(得分:0)

到目前为止,您向我们展示的内容表明您处于写作轨道上。例如,请考虑以下XML

<body>
   <ul>A. The definition of "Panoply" is:</ul> 
   <ul>
      <ul>A Large assortment</ul>
   </ul>
</body>

如果你把我们展示给我们的两个模板放到XSLT中,那么你的XSLT可能看起来像这样

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output method="xml" indent="yes"/>

   <xsl:template match="ul">
      <para>
         <xsl:apply-templates select="*|@*|text()"/>
      </para>
   </xsl:template>

   <xsl:template match="ul/ul">
      <xsl:apply-templates select="*|@*|text()"/>
   </xsl:template>

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

当这应用于上述XML时,输出如下

<body>
   <para>A. The definition of "Panoply" is:</para>
   <para>A Large assortment</para>
</body>

此时值得一读resolving template conflicts。在您的情况下,这意味着模板匹配 ul / ul 将始终匹配模板匹配 ul

但是你也想要一个关于用块引用替换“double ul”的规则。在这种情况下,只需将以下模板添加到上面的XML

<xsl:template match="ul[ul]">
   <blockquote>
      <xsl:apply-templates select="*|@*|text()"/>
   </blockquote>
</xsl:template>

当修改后的XSLT应用于XML时,您应该得到以下输出

<body>
    <para>A. The definition of "Panoply" is:</para>
    <blockquote>A Large assortment</blockquote>
</body>

值得指出的是,回到模板冲突的主题,如果你有 ul 元素嵌套到三个元素,如此

<ul>
   <ul>
     <ul>A Large assortment</ul>
  </ul>
</ul>

然后 ul / ul ul [ul] 模板匹配中间的 ul ,这将被认为是除非您在模板上设置了优先级,否则会出错。

答案 2 :(得分:0)

您可以为元素向上设置特殊匹配规则 - 使用父元素

<xsl:template match="ul[name(parent::*) = 'ul']">

- 以及所有子元素

<xsl:template match="ul[name(child::*[1]) = 'ul']" >

这样的事情应该做:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="xml" indent="yes" />
    <xsl:strip-space elements="*"/>

    <xsl:template match="ul">
        <para>
            <xsl:apply-templates select="*|@*|text()"/>
        </para>
    </xsl:template>

    <xsl:template match="ul[name(child::*[1]) = 'ul']" >
        <xsl:apply-templates />
    </xsl:template>

    <xsl:template match="ul[name(parent::*) = 'ul']">
        <blockquote><xsl:apply-templates select="*|@*|text()"/></blockquote>
    </xsl:template>
</xsl:stylesheet>