XSLT"移动"兄弟姐妹的内容成为封闭的前兄弟

时间:2017-07-31 16:02:38

标签: xslt xslt-1.0

我的输入有一些我想要解决的不符合标记,例如

<ul>
  <li>
  </li>
  <p>This is the first bullet item</p>
  <li>
  </li>
  <p>This is the second bullet item</p>
</ul>
...
<ul>
  <li>I am fine. No need to monkey with me.</li>
<ul>

应该是

<ul>
  <li>This is the first bullet item</li>
  <li>This is the second bullet item</li>
</ul>
...
<ul>
  <li>I am fine. No need to monkey with me.</li>
<ul>

我知道怎样&#34;展开&#34; p元素

<xsl:template match="p[parent::ul and preceding-sibling::li]">
    <!-- Don't wrap or copy. Just process content. -->
    <xsl:apply-templates/>
</xsl:template>

但我无法弄清楚如何让展开的p内容出现在输出中的li内。不知何故,我猜测,我需要识别空的li,而是创建一个新的li,然后添加以下兄弟p的内容。像

这样的东西
<xsl:template match="li[not(li) and not(normalize-space())]">
    <li>
        <!-- how do I get content of following-sibling p here?? -->
        <xsl:apply-templates/>
    </li>
</xsl:template>

但这(显然)不起作用。我卡住了,无法找到解决方案。建议?

2 个答案:

答案 0 :(得分:2)

  

不知何故,我猜测,我需要识别空的lis,而是创建一个新的li,然后添加以下兄弟p的内容。

这似乎是一个好主意,所以试试这个:

<xsl:template match="li[normalize-space(text())='']">
  <xsl:copy>
    <xsl:value-of select="following-sibling::p[1]/text()" />
  </xsl:copy>
</xsl:template>

这会使用以下li元素的text()填充空的p元素。

要摆脱p元素,(稍微)反转XPath表达式并将其放在一个空模板中:

<xsl:template match="p[normalize-space(preceding-sibling::li[1]/text())='']" />

输出是:

<ul>
  <li>This is the first bullet item</li>
  <li>This is the second bullet item</li>
</ul>

答案 1 :(得分:1)

为什么你不做:

<xsl:template match="ul">
    <xsl:copy>
        <xsl:for-each select="li">
            <xsl:copy>
                <xsl:value-of select="following-sibling::p[1]" />
            </xsl:copy>
        </xsl:for-each>
    </xsl:copy>
</xsl:template>

或者,如果您愿意:

<xsl:template match="ul">
    <xsl:copy>
        <xsl:for-each select="p">
            <li>
                <xsl:apply-templates/>
            </li>
        </xsl:for-each>
    </xsl:copy>
</xsl:template>

在回复编辑问题时添加:

如果此问题仅影响某些ul个节点,则可以通过更改以下内容来限制模板:

<xsl:template match="ul">

为:

<xsl:template match="ul[p]">

或:

<xsl:template match="ul[li[not(normalize-space())]]">