[英]Split XML with XSLT 1.0 at the location of a particular tag, and maintain HTML markup throughout results
I need to transform the following XML by splitting at the <hr/>
tag. 我需要通过分割<hr/>
标记来转换以下XML。 The content on either side of the split should then be stored as params, and output within separate divs. 然后应将拆分两侧的内容存储为参数,并在单独的div中输出。
I'm running into several issues: 我遇到了几个问题:
1) I can't seem to use the <hr/>
tag as the separator for this. 1)我似乎无法使用<hr/>
标记作为分隔符。 I assume that's due to the parser stripping the tag prior to setting the new params? 我认为是由于解析器在设置新参数之前剥离了标签? Is there a workaround for this? 有没有解决方法? I do have control over the XML output within the <bodyText>
node, and while I could use a specified string instead, the <hr/>
tag makes for a more reliable flag maintenance-wise. 我确实可以控制<bodyText>
节点内的XML输出,虽然我可以使用指定的字符串代替,但是<hr/>
标记使标记维护更可靠。
2) While <xsl:copy-of select="$desc"/>
produces the full contents with HTML markup intact (which I need), $shortDesc
and $longDesc
both return the bare / stripped text content. 2)虽然<xsl:copy-of select="$desc"/>
产生完整的HTML标记完整内容(我需要),但$shortDesc
和$longDesc
都返回裸/剥离文本内容。 How can I retain the HTML markup? 如何保留HTML标记?
Essentially I need to split the XML at the point of the <hr/>
tag, and then copy the before and after contents into separate divs with markup intact. 本质上,我需要在<hr/>
标记处拆分XML,然后将之前和之后的内容复制到具有完整标记的单独的div中。
I've seen a few posts with challenges quite close to this, but each just different enough that I've been unable to resolve. 我看到了几篇与挑战非常接近的文章,但每篇文章都相差甚远,以至于我无法解决。
The XML: XML:
<bodyText>
<p>Lorem Ipsum Short</p>
<hr/>
<p>Lorem Ipsum Long</p>
</bodyText>
*And please note that the XML feed is admin-generated, so this is just a basic example. *并且请注意,XML提要是管理员生成的,因此这只是一个基本示例。 The actual feed is not dependable, only that there will be an <hr/>
for where the split should occur. 实际的提要并不可靠,只是在应该进行拆分的位置存在一个<hr/>
。
The XSL: XSL:
<xsl:template name="ExpandContent_main">
<xsl:param name="desc" select="/bodyText"/>
<xsl:param name="separator" select="'<hr/>'"/>
<xsl:param name="shortDesc" select="substring-before($desc, $separator)"/>
<xsl:param name="longDesc" select="substring-after($desc, $separator)"/>
<div class="short-description">
<xsl:copy-of select="$shortDesc"/>
</div>
<div class="long-description">
<xsl:copy-of select="$longDesc"/>
</div>
</xsl:template>
The expected output: 预期输出:
<div class="short-description">
<p>Lorem Ipsum Short</p>
</div>
<div class="long-description">
<p>Lorem Ipsum Long</p>
</div>
Your mistake is that you are trying to use string functions on nodes. 您的错误是您试图在节点上使用字符串函数。 Now, I don't think you need a named template for this. 现在,我认为您不需要为此命名的模板。 Consider the following stylesheet: 考虑以下样式表:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="bodyText">
<div class="short-description">
<xsl:apply-templates select="p[not(preceding-sibling::hr)]"/>
</div>
<div class="long-description">
<xsl:apply-templates select="p[preceding-sibling::hr]"/>
</div>
</xsl:template>
</xsl:stylesheet>
When applied to the following test input: 当应用于以下测试输入时:
<content>
<bodyText>
<p>Lorem <i>Ipsum</i> Short</p>
<hr/>
<p>Lorem <b>Ipsum</b> Long</p>
</bodyText>
</content>
the result will be: 结果将是:
<?xml version="1.0" encoding="UTF-8"?>
<content>
<div class="short-description">
<p>Lorem <i>Ipsum</i> Short</p>
</div>
<div class="long-description">
<p>Lorem <b>Ipsum</b> Long</p>
</div>
</content>
<xsl:template match="bodyText"> <div class="short-description"> <xsl:copy-of select="node()[following-sibling::hr]"/> </div> <div class="long-description"> <xsl:copy-of select="node()[preceding-sibling::hr]"/> </div> </xsl:template>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.