在元素之间选择多个text()节点



我需要将以下xml输出到浏览器,如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<content>
<text>
<h1>Services</h1>
<h2>Engineering</h2>
This is the first bit of text:
<listofitems>
<listitem>Database Analysis Tools</listitem>
<listitem>Website Development</listitem>
<listitem>Intranet Development</listitem>
<listitem>Database Development</listitem>
</listofitems> 
This is the second piece of text:
<listofitems>
<listitem>Hardware</listitem>
<listitem>Software</listitem>
</listofitems>
This is the final piece of text.
</text>
</content>

问题在于<文本>元素-未包含在其自己的标记中的位,即"This is the first bit of text:"、"This are the second piece of text:"one_answers"This是最后一段文本。">

如果我使用<xsl:value-of-select="."/>,但很明显,它们在原始XML中并不是这样出现的。如果我使用<xsl:value-of-select="text()"/>我一无所获(我相信text()只引用了第一个子节点,在本例中它是另一个元素)。

我可以用<xsl:value-of-select="node()[last()]/self::text()">;我可以通过直接引用每个text()节点来访问它,例如<xsl:value-of-select="text()[3]"/>,但由于这意味着要与任何格式的随机XML一起使用,我将无法以这种方式直接引用节点。我在text()[*]上尝试了for each,但没有成功。你知道我该怎么做吗?

如果文本节点是text元素的子元素,则编写一个单独的模板来匹配它们:

<xsl:template match="text()[parent::text]">

这样,介于两者之间的任何其他子元素都不会干扰。然后,编写第二个模板来防止XSLT处理器也在listitem元素内部输出文本:

<xsl:template match="*[parent::text]"/>

如果您省略了上面的模板匹配,XSLT的默认行为将导致作为listitem的子级的任何文本节点也被输出。

请注意,XSLT1.0和2.0在处理文本节点方面有所不同。您的方法之一:

<xsl:value-of select="text()"/>

实际上输出XSLT2.0中的所有文本节点。下面是一个适用于1.0和2.0的样式表。

样式表

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<xsl:template match="//text">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="text()[parent::text]">
<xsl:value-of select="."/>
</xsl:template>
<xsl:template match="*[parent::text]"/>
</xsl:stylesheet>

输出

This is the first bit of text: This is the second piece of text: This is the final piece of text.

或者,如果不需要处理text的子元素,请将select属性添加到apply-templates:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="//text">
<xsl:apply-templates select="text()"/>
</xsl:template>
<xsl:template match="text()[parent::text]">
<xsl:copy/>
</xsl:template>
</xsl:stylesheet>

当这个样式表:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="content/text/text()">
<span><xsl:value-of select="."/></span>
</xsl:template>
</xsl:stylesheet>

应用于您的输入。它输出:

<?xml version="1.0" encoding="utf-8"?>
<content>
<text>
<h1>Services</h1>
<h2>Engineering</h2>
<span>This is the first bit of text:</span>
<listofitems>
<listitem>Database Analysis Tools</listitem>
<listitem>Website Development</listitem>
<listitem>Intranet Development</listitem>
<listitem>Database Development</listitem>
</listofitems>
<span>This is the second piece of text:</span>
<listofitems>
<listitem>Hardware</listitem>
<listitem>Software</listitem>
</listofitems>
<span>This is the final piece of text.</span>
</text>
</content>

这能解决你的问题吗?

经过多次摆弄,我认为这已经足够接近了,可以接受:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="*">
<xsl:param name="indent"/>
<xsl:if test="parent::* or preceding-sibling::*">
<br/>
</xsl:if>
<xsl:value-of select="$indent" disable-output-escaping="yes"/>
<!-- open angle brackets -->
&lt;<xsl:value-of select="name()"/>
<!-- output any attributes and values -->
<xsl:for-each select="@*">
<xsl:text disable-output-escaping="yes">&amp;nbsp;</xsl:text>
<xsl:value-of select="name(.)"/>="<b><xsl:value-of select="."/></b>"
</xsl:for-each>
<!-- close angle brackets -->
&gt;
<!-- output text content -->
<xsl:apply-templates>
<xsl:with-param name="indent"><xsl:value-of select="$indent"/>&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;</xsl:with-param>
</xsl:apply-templates>
<!-- close tag -->
<xsl:if test="child::*">
<br/><xsl:value-of select="$indent" disable-output-escaping="yes"/>
</xsl:if>
&lt;/<xsl:value-of select="name()"/>&gt;  
</xsl:template>
<xsl:template match="text()">
<xsl:value-of select="."/>
</xsl:template>
</xsl:stylesheet>

这就给出了:

<content> 
<text> 
<h1>Services</h1> 
<h2>Engineering</h2> This is the first bit of text: 
<listofitems> 
<listitem>Database Analysis Tools</listitem> 
<listitem>Website Development</listitem> 
<listitem>Intranet Development</listitem> 
<listitem>Database Development</listitem> 
</listofitems> This is the second piece of text: 
<listofitems> 
<listitem>Hardware</listitem> 
<listitem>Software</listitem> 
</listofitems> This is the final piece of text. 
</text> 
</content>

这些烦人的文本片段至少在大致正确的区域,模板应该可以与任何旧的XML一起使用

非常感谢你的帮助。

相关内容

  • 没有找到相关文章

最新更新