xml – 创建一个XSL样式表,根据输入参数省略不需要的元素
这将是一个有点长和具体,所以请耐心等待.我理解XSLT是如何工作的,但我不知道执行操作的所有元素.您可以提供的任何帮助将不胜感激.
假设我有一本用XML编写的737s试用手册.但是,有3种类型的737(400,600和800),虽然90%的手册对于所有三种类型都是相同的,但是只有每种类型的特定部分.一些飞行员只会学习1或2(或有时是所有3)喷气机,所以我想省略与它们无关的部分.以下是我设置XML的方法: <manual> <section>A: This is relevant for every type</section> <section t600="no" t800="no">B: This is relevant only for the 737-400</section> <section t800="no">C: This is relevant for 737-400 and 737-600</section> <section t400="no">D: This is relevant for 737-600 and 737-800</section> </manual> 我希望能够以某种方式指定我只对737-800感兴趣,并得到这样的手册: <manual> <section>A: This is relevant for every type</section> <section>D: This is relevant for 737-600 and 737-800</section> </manual> 或者对于对两架喷气机感兴趣的不同飞行员,比如737-400和737-600,手册看起来像这样: <manual> <section>A: This is relevant for every type</section> <section>B: This is relevant only for the 737-400</section> <section>C: This is relevant for 737-400 and 737-600</section> <section>D: This is relevant for 737-600 and 737-800</section> </manual> 我可以访问源XML,所以如果我设置它的方式没有意义我可以改变它.我的想法是因为几乎所有类型的一切都是相同的,选择退出更有意义,但我意识到这可能会让它更难匹配?我不确定. 再次感谢您一起来看看!如果我遗漏了一些东西,请告诉我.
I. XSLT 2.0解决方案:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs"> <xsl:output omit-xml-declaration="yes" indent="yes"/> <xsl:strip-space elements="*"/> <xsl:param name="pInterests"> <interest topic="t800"/> </xsl:param> <xsl:template match="node()|@*"> <xsl:copy> <xsl:apply-templates select="node()|@*"/> </xsl:copy> </xsl:template> <xsl:template match= "section[some $t in $pInterests/*/@topic satisfies not($t = current()/@*[. eq 'no']/name()) ] "> <section><xsl:apply-templates/></section> </xsl:template> <xsl:template match="section"/> </xsl:stylesheet> 当应用于提供的XML文档时: <manual> <section>A: This is relevant for every type</section> <section t600="no" t800="no">B: This is relevant only for the 737-400</section> <section t800="no">C: This is relevant for 737-400 and 737-600</section> <section t400="no">D: This is relevant for 737-600 and 737-800</section> </manual> 产生想要的,正确的结果: <manual> <section>A: This is relevant for every type</section> <section>D: This is relevant for 737-600 and 737-800</section> </manual> 如果我们在转换中替换当前参数: <xsl:param name="pInterests"> <interest topic="t800"/> </xsl:param> 有: <xsl:param name="pInterests"> <interest topic="t400"/> <interest topic="t600"/> </xsl:param> 并再次对同一XML文档应用修改后的转换,我们也得到了想要的正确结果: <manual> <section>A: This is relevant for every type</section> <section>B: This is relevant only for the 737-400</section> <section>C: This is relevant for 737-400 and 737-600</section> <section>D: This is relevant for 737-600 and 737-800</section> </manual> II. XSLT 1.0解决方案: <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output omit-xml-declaration="yes" indent="yes"/> <xsl:strip-space elements="*"/> <xsl:param name="pInterests"> <interest topic="t800"/> </xsl:param> <xsl:key name="kSectionTypeAttrByName" match="section/@*" use="concat(generate-id(..),'|',name())"/> <xsl:variable name="vInterests" select= "document('')/*/xsl:param[@name='pInterests']/*"/> <xsl:template match="node()|@*"> <xsl:copy> <xsl:apply-templates select="node()|@*"/> </xsl:copy> </xsl:template> <xsl:template match="section"> <xsl:variable name="vSec" select="."/> <xsl:variable name="vHasInterest"> <xsl:for-each select="$vInterests/@topic"> <xsl:variable name="vTopic" select="."/> <xsl:for-each select= "$vSec[not(key('kSectionTypeAttrByName',concat(generate-id(),$vTopic) ) = 'no' ) ]"> <xsl:text>1</xsl:text> </xsl:for-each> </xsl:for-each> </xsl:variable> <xsl:if test="string($vHasInterest)"> <section><xsl:apply-templates/></section> </xsl:if> </xsl:template> </xsl:stylesheet> 当应用于提供的XML文档时: <manual> <section>A: This is relevant for every type</section> <section t600="no" t800="no">B: This is relevant only for the 737-400</section> <section t800="no">C: This is relevant for 737-400 and 737-600</section> <section t400="no">D: This is relevant for 737-600 and 737-800</section> </manual> 产生想要的,我们也得到了想要的正确结果: <manual> <section>A: This is relevant for every type</section> <section>B: This is relevant only for the 737-400</section> <section>C: This is relevant for 737-400 and 737-600</section> <section>D: This is relevant for 737-600 and 737-800</section> </manual> (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |