我需要将以下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>
问题在于&lt; text&gt;中的文本字符串。 element - 未包含在自己标签中的位,即“这是文本的第一位:','这是第二段文字:'和'这是最后一段文字。'
如果我使用&lt; xsl:value-of select =“。”/&gt;,我可以在一个块中输出所有三位文本,但显然这不是它们在原始XML中的显示方式。如果我使用&lt; xsl:value-of select =“text()”/&gt;什么都没有回来(我相信text()只引用第一个子节点,在这种情况下是另一个元素)。
我可以用&lt; xsl:value-of select =“node()[last()] / self :: text()”&gt ;;输出最后一位文本。我可以通过直接引用它来访问每个text()节点,例如&lt; xsl:value-of select =“text()[3]”/&gt;,但因为这意味着要使用随机XML,它可以是任何格式,我将无法直接在此引用节点办法。我在text()[*]上尝试过for-each,但它没有用。我有什么想法可以做到这一点吗?
答案 0 :(得分:1)
如果文本节点是text
元素的子元素,则编写单独的模板以匹配文本节点:
<xsl:template match="text()[parent::text]">
这样,其间的任何其他子元素都不会干扰。然后,编写第二个模板,以防止XSLT处理器在listitem
元素内输出文本:
<xsl:template match="*[parent::text]"/>
如果省略了上面的模板匹配,XSLT的默认行为将导致同时输出listitem
子项的任何文本节点。
请注意,XSLT 1.0和2.0在处理文本节点方面存在差异。你的一种方法:
<xsl:value-of select="text()"/>
实际上是否在XSLT 2.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>
答案 1 :(得分:0)
当这个样式表:
<?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>
这会解决你的问题吗?
答案 2 :(得分:0)
经过多次摆弄后,我认为这已经足够接近了:
<?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 -->
<<xsl:value-of select="name()"/>
<!-- output any attributes and values -->
<xsl:for-each select="@*">
<xsl:text disable-output-escaping="yes">&nbsp;</xsl:text>
<xsl:value-of select="name(.)"/>="<b><xsl:value-of select="."/></b>"
</xsl:for-each>
<!-- close angle brackets -->
>
<!-- output text content -->
<xsl:apply-templates>
<xsl:with-param name="indent"><xsl:value-of select="$indent"/>&nbsp;&nbsp;&nbsp;&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>
</<xsl:value-of select="name()"/>>
</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一起使用。
非常感谢你的帮助。