如何使用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>
基本上规则是:
以下是我使用MarcoS关于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>
答案 0 :(得分:5)
这是一种可能的解决方案(可能不是很优雅):
<?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:template match="file">
<file>
<xsl:for-each select="row">
<xsl:if test="(position() >= 3 and position() < 5)
or (position() >= 7 and position() <= 8)">
<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>
</file>
</xsl:template>
</xsl:stylesheet>
基本上,您可以使用XPath position()
函数来选择所需的row
和cell
元素的范围。
答案 1 :(得分:2)
这是一个XSLT,可以完成你描述的内容。
<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" encoding="iso-8859-1" indent="yes" omit-xml-declaration="no"/>
<xsl:template match="file">
<xsl:copy>
<xsl:apply-templates select="row[(position()>=3 and position()<=5) or (position()>=7 and position()<=8)]" />
</xsl:copy>
</xsl:template>
<xsl:template match="row">
<xsl:copy>
<xsl:apply-templates select="cell[position()=1 or position()=3]" />
</xsl:copy>
</xsl:template>
<xsl:template match="cell">
<xsl:copy-of select="." />
</xsl:template>
</xsl:stylesheet>
要在输出中选择所需的行,我想我首先要用一个可用作过滤器的属性来标记它们。 在调用XSLT的代码中,您可以在加载XML文档之后和应用转换之前使用DOM方法来完成。例如,保留吉姆史密斯但丢弃罗伊罗杰斯:
<row keep="-1">
<cell>Jim</cell>
<cell>Smith</cell>
<cell>34</cell>
</row>
<row>
<cell>Roy</cell>
<cell>Rogers</cell>
<cell>22</cell>
</row>
并将XSLT中的行更改为:
<xsl:apply-templates select="row[@keep=-1]" />
答案 2 :(得分:2)
这可能是最简单,最简短的解决方案,也基于使用和覆盖身份规则:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="my:my">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<my:params>
<row-range start="3" end="5"/>
<row-range start="7" end="8"/>
<cell-positions>
<pos>1</pos>
<pos>3</pos>
</cell-positions>
</my:params>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match=
"row[(not(position() >= document('')/*/my:params/row-range[1]/@start)
or
position() > document('')/*/my:params/row-range[1]/@end
)
and
(not(position() >= document('')/*/my:params/row-range[2]/@start)
or
position() > document('')/*/my:params/row-range[2]/@end
)
]
"/>
<xsl:template match=
"cell[not(position()=document('')/*/my:params/cell-positions/*)]"/>
</xsl:stylesheet>
在提供的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>
产生了想要的正确结果:
<file>
<row>
<cell>Jim</cell>
<cell>34</cell>
</row>
<row>
<cell>Roy</cell>
<cell>22</cell>
</row>
<row>
<cell>Hank</cell>
<cell>23</cell>
</row>
<row>
<cell>Sally</cell>
<cell>26</cell>
</row>
<row>
<cell>John</cell>
<cell>44</cell>
</row>
</file>