如何使用XSLT仅获取某些行和某些列?
我如何使用 XSLT 将此 XML 文件转换
<file>
<row>
<cell></cell>
<cell>(info...)</cell>
<cell></cell>
</row>
<row>
<cell>first name</cell>
<cell>last name</cell>
<cell>age</cell>
</row>
<row>
<cell>Jim</cell>
<cell>Smith</cell>
<cell>34</cell>
</row>
<row>
<cell>Roy</cell>
<cell>Rogers</cell>
<cell>22</cell>
</row>
<row>
<cell>Hank</cell>
<cell>Grandier</cell>
<cell>23</cell>
</row>
<row>
<cell>(info...)</cell>
<cell></cell>
<cell>(info...)</cell>
</row>
<row>
<cell>Sally</cell>
<cell>Cloud</cell>
<cell>26</cell>
</row>
<row>
<cell>John</cell>
<cell>Randall</cell>
<cell>44</cell>
</row>
</file>
为此 XML 文件:
<file>
<row>
<cell>Jim</cell>
<cell>34</cell>
</row>
<row>
<cell>Roy</cell>
<cell>22</cell>
</row>
<row>
<cell>Sally</cell>
<cell>26</cell>
</row>
<row>
<cell>John</cell>
<cell>44</cell>
</row>
</file>
基本上规则是:
- 仅第一和第三列(名字和年龄)
- 仅特定范围内的行,例如在简单的示例中上面将是第3-5行和第7-8行,所以我假设我需要某种包含此信息的映射表
附录
这是我的解决方案MarcoS 关于参数的提示:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="xml" indent="yes" omit-xml-declaration="no" />
<xsl:param name="range-1-begin" select="3"/>
<xsl:param name="range-1-end" select="4"/>
<xsl:param name="range-2-begin" select="6"/>
<xsl:param name="range-2-end" select="7"/>
<xsl:template match="file">
<marco>
<xsl:for-each select="row">
<xsl:if test="(position() >= $range-1-begin and position() <= $range-1-end)
or (position() >= $range-2-begin and position() <= $range-2-end)">
<row>
<xsl:for-each select="cell">
<xsl:if test="position() = 1 or
position() = 3">
<cell>
<xsl:value-of select="."/>
</cell>
</xsl:if>
</xsl:for-each>
</row>
</xsl:if>
</xsl:for-each>
</marco>
</xsl:template>
</xsl:stylesheet>
How can I use XSLT to convert this XML file:
<file>
<row>
<cell></cell>
<cell>(info...)</cell>
<cell></cell>
</row>
<row>
<cell>first name</cell>
<cell>last name</cell>
<cell>age</cell>
</row>
<row>
<cell>Jim</cell>
<cell>Smith</cell>
<cell>34</cell>
</row>
<row>
<cell>Roy</cell>
<cell>Rogers</cell>
<cell>22</cell>
</row>
<row>
<cell>Hank</cell>
<cell>Grandier</cell>
<cell>23</cell>
</row>
<row>
<cell>(info...)</cell>
<cell></cell>
<cell>(info...)</cell>
</row>
<row>
<cell>Sally</cell>
<cell>Cloud</cell>
<cell>26</cell>
</row>
<row>
<cell>John</cell>
<cell>Randall</cell>
<cell>44</cell>
</row>
</file>
to this XML file:
<file>
<row>
<cell>Jim</cell>
<cell>34</cell>
</row>
<row>
<cell>Roy</cell>
<cell>22</cell>
</row>
<row>
<cell>Sally</cell>
<cell>26</cell>
</row>
<row>
<cell>John</cell>
<cell>44</cell>
</row>
</file>
Basically the rules are:
- only first and third column (first name and age)
- only rows within certain ranges, e.g. in the simple example above it would be rows 3-5 and rows 7-8 so I would assume I would need some kind of mapping table with this information in it
Addendum
Here is my solution using MarcoS's tip about params:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="xml" indent="yes" omit-xml-declaration="no" />
<xsl:param name="range-1-begin" select="3"/>
<xsl:param name="range-1-end" select="4"/>
<xsl:param name="range-2-begin" select="6"/>
<xsl:param name="range-2-end" select="7"/>
<xsl:template match="file">
<marco>
<xsl:for-each select="row">
<xsl:if test="(position() >= $range-1-begin and position() <= $range-1-end)
or (position() >= $range-2-begin and position() <= $range-2-end)">
<row>
<xsl:for-each select="cell">
<xsl:if test="position() = 1 or
position() = 3">
<cell>
<xsl:value-of select="."/>
</cell>
</xsl:if>
</xsl:for-each>
</row>
</xsl:if>
</xsl:for-each>
</marco>
</xsl:template>
</xsl:stylesheet>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这是一个可能的解决方案(可能不是很优雅):
本质上,您可以使用 XPath
position()
函数来选择row
和cell
的范围> 您想要的元素。This is a possible solution (maybe not very elegant):
Essentially, you can use XPath
position()
function to select the ranges ofrow
andcell
elements that you want.这是执行您所描述的操作的 XSLT 片段。
要在输出中选择所需的行,我想我首先要使用将用作过滤器的属性来标记它们。
在调用 XSLT 的代码中,您可以在加载 XML 文档之后和应用转换之前使用 DOM 方法来执行此操作。例如,保留 Jim Smith 但放弃 Roy Rogers:
并将 XSLT 中的行更改为:
Here's a piece of XSLT that does what you describe.
To select the rows you want in your output, I think I'd begin by marking them with an attribute which would be used as a filter.
In the code invoking the XSLT, you could do it using DOM methods just after loading the XML document and before applying the transformation. Eg to keep Jim Smith but discard Roy Rogers:
And change the line in the XSLT to:
这可能是最简单、最短的解决方案,也基于使用和覆盖身份规则:
当此转换应用于提供的 XML 文档时:
想要的,产生正确的结果:
This is probably the simplest and shortest solution, also based on using and overriding the identity rule:
When this transformation is applied on the provided XML document:
the wanted, correct result is produced: