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>。我想将 double<ul>变成 a <blockquote>,但它已经<para>从另一个模板中提取,并且我正在使用的 dtd 不允许 paras 中的块引用

另一个编辑

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

<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>
4

3 回答 3

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>

第二个模板只匹配ulul孩子的 s 并且只处理这些孩子的内容。第一个模板匹配所有其他ul节点。

于 2013-04-26T20:23:12.030 回答
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>

在这一点上解决模板冲突值得一读。在您的情况下,这意味着模板匹配ul/ul将始终在模板匹配ul之前匹配。

但是您还需要一条关于用块引用替换“双 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/ulul[ul]模板匹配,除非您在模板上指定优先级,否则这将被视为错误。

于 2013-04-26T20:30:20.617 回答
0

您可以为 elment up 设置特殊匹配规则
- 使用父 ul 元素

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

- 并带有 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>
于 2013-04-26T20:36:24.730 回答