所以我正忙于创建一个XSLT文件,将各种XML文档处理到一个新的节点布局中。
有一件事我想不通,下面是我正在使用的XML示例:
<page>
This is a paragraph on the page.
<newParagraph/>
This is another paragraph.
<newParagraph/>
Here is yet another paragraph on this page.
<page>
正如你所看到的,段落是用空标签作为分隔符来分割的。在结果XML中,我想要这个:
<page>
<p>
This is a paragraph on the page.
</p>
<p>
This is another paragraph.
</p>
<p>
Here is yet another paragraph on this page.
</p>
<page>
如何使用XSLT(仅1.0版)实现这一点?
这或多或少是另一个问题的重复,所以同样的方法也可以:
<xsl:template match="pages">
<xsl:apply-templates />
</xsl:template>
<xsl:template match="page/text()">
<p><xsl:value-of select="."/></p>
</xsl:template>
<xsl:template match="NewParagraph" />
简单干净。希望它能帮助
下面的答案没有@stwisel的那么优雅,但它可以纠正段落中的任何标记子树。它确实变得有点令人讨厌。:-)
此任务的问题在于,它需要特殊处理关闭标记和随后匹配的打开标签之间的内容(例如<tag></tag>
)。然而,XSLT经过优化,可以处理介于开始标记和匹配的结束标记(例如</tag><tag>
)之间的内容。顺便说一句:有一种方法可以稍微"欺骗"一下。看看我对这个问题的另一个回答。
假设您有一个输入XML,如下所示:
<pages>
<page>
This is a paragraph on the page.
<B>bold</B>
After Bold
<newParagraph/>
This is another paragraph.
<newParagraph/>
Here is yet another paragraph on this page.
<EM>
<B>
Bold and emphasized.
</B>
</EM>
After bold and emphasized.
</page>
<page>
Another page.
</page>
</pages>
它可以使用这个XSLT1.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="xml" version="1.0" encoding="UTF-8" indent="yes" />
<xsl:template match="page">
<page>
<!-- handle the first paragraph up to the first newParagraph -->
<P>
<xsl:apply-templates select="node()[not(preceding-sibling::newParagraph)]" />
</P>
<!-- now handle all remaining paragraphs of the page -->
<xsl:for-each select="newParagraph">
<xsl:variable name="pCount" select="position()"/>
<P>
<xsl:apply-templates select="following-sibling::node()[count(preceding-sibling::newParagraph) <= $pCount]" />
</P>
</xsl:for-each>
</page>
</xsl:template>
<!-- this default rule recursively copies all substructures within a paragraph at tag level -->
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<!-- this default rule makes sure that texts between the tags are printed -->
<xsl:template match="text()">
<xsl:copy-of select="."/>
</xsl:template>
<xsl:template match="newParagraph"/>
</xsl:stylesheet>
产生该输出
<pages>
<page><P>
This is a paragraph on the page.
<B>bold</B>
After Bold
</P><P>
This is another paragraph.
</P><P>
Here is yet another paragraph on this page.
<EM>
<B>
Bold and emphasized.
</B>
</EM>
After bold and emphasized.
</P></page>
<page><P>
Another page.
</P></page>
</pages>
如果您愿意"欺骗"一点,您可以手动将XML标记插入到结果文档中,这些标记不是节点树的一部分,而是普通文本。然而,下游处理器不会注意到差异,前提是它重新解析输出。
如果输入了我的另一个答案,下面的XSLT1.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="xml" version="1.0" encoding="UTF-8" indent="yes" />
<xsl:template match="page">
<page>
<P>
<xsl:apply-templates/>
</P>
</page>
</xsl:template>
<!-- this default rule recursively copies all substructures within a paragraph at tag level -->
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<!-- this default rule makes sure that texts between the tags are printed -->
<xsl:template match="text()">
<xsl:copy-of select="."/>
</xsl:template>
<xsl:template match="newParagraph">
<!-- This inserts a matching closing and opening tag -->
<xsl:value-of select="'</P><P>'" disable-output-escaping="yes" />
</xsl:template>
</xsl:stylesheet>