XSLT 多输出:复制选定的节点和其余节点
XSLT multiple output: copy selected nodes and the rest too
我有以下输入 xml:
<?xml version="1.0" encoding="UTF-8"?>
<car xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<extras>
<extra>
<model>Z1</model>
</extra>
<extra>
<model>Z2</model>
</extra>
<extra>
<model>X</model>
</extra>
</extras>
<color>red</color>
<tire>goodyear</tire>
</car>
我正在尝试为每个 <extra>..</extra>
元素生成一个输出 xml,结果 xmls 应该包含输入中的所有元素,但只包含一个特定的元素<extra>
元素。
即,结果输出应为:
extra1.xml:
<?xml version="1.0" encoding="UTF-8"?>
<car xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<extras>
<extra>
<model>Z1</model>
</extra>
</extras>
<color>red</color>
<tire>goodyear</tire>
</car>
extra2.xml:
<?xml version="1.0" encoding="UTF-8"?>
<car xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<extras>
<extra>
<model>Z2</model>
</extra>
</extras>
<color>red</color>
<tire>goodyear</tire>
</car>
extra3.xml:
<?xml version="1.0" encoding="UTF-8"?>
<car xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<extras>
<extra>
<model>X</model>
</extra>
</extras>
<color>red</color>
<tire>goodyear</tire>
</car>
我使用的是 XSLT 2.0 Saxon-HE 9.6.0-5。
我的 xslt 如下所示:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="xml" encoding="UTF-8" indent="yes" />
<xsl:strip-space elements="*" />
<xsl:template name="full">
<xsl:param name="enode" />
<xsl:for-each select="/">
<xsl:if test="*[not($enode = current())]">
<xsl:copy-of select="current()" />
</xsl:if>
</xsl:for-each>
</xsl:template>
<xsl:template match="extras">
<xsl:for-each select="//extra">
<xsl:result-document href="extra{position()}.xml">
<xsl:call-template name="full">
<xsl:with-param name="enode" select="current()" />
</xsl:call-template>
<extras>
<xsl:copy-of select="current()" />
</extras>
</xsl:result-document>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
我能够生成仅包含一个 <extra>
元素的输出 xmls,但是如何从输入中复制其余元素(即:
<extras>
的子元素除外的所有元素?)
我试图创建一个模板 "full",它循环遍历所有节点并仅复制那些与我作为参数传递的节点 (enode) 不同的节点,但没有成功。
是否有任何(其他)方法可以获得所需的结果?
如果生成的 xml 中元素的顺序与我提供的不同,这不是问题,我可以在第二遍中重新排列它们。
能不能简单点:
XSLT 2.0
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:output method="xml" encoding="UTF-8" indent="yes" />
<xsl:strip-space elements="*" />
<xsl:template match="/car">
<xsl:for-each select="extras/extra">
<xsl:result-document href="extra{position()}.xml">
<car xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<extras>
<xsl:copy-of select="*"/>
</extras>
<xsl:copy-of select="../../(* except extras)"/>
</car>
</xsl:result-document>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
我有以下输入 xml:
<?xml version="1.0" encoding="UTF-8"?>
<car xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<extras>
<extra>
<model>Z1</model>
</extra>
<extra>
<model>Z2</model>
</extra>
<extra>
<model>X</model>
</extra>
</extras>
<color>red</color>
<tire>goodyear</tire>
</car>
我正在尝试为每个 <extra>..</extra>
元素生成一个输出 xml,结果 xmls 应该包含输入中的所有元素,但只包含一个特定的元素<extra>
元素。
即,结果输出应为:
extra1.xml:
<?xml version="1.0" encoding="UTF-8"?>
<car xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<extras>
<extra>
<model>Z1</model>
</extra>
</extras>
<color>red</color>
<tire>goodyear</tire>
</car>
extra2.xml:
<?xml version="1.0" encoding="UTF-8"?>
<car xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<extras>
<extra>
<model>Z2</model>
</extra>
</extras>
<color>red</color>
<tire>goodyear</tire>
</car>
extra3.xml:
<?xml version="1.0" encoding="UTF-8"?>
<car xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<extras>
<extra>
<model>X</model>
</extra>
</extras>
<color>red</color>
<tire>goodyear</tire>
</car>
我使用的是 XSLT 2.0 Saxon-HE 9.6.0-5。
我的 xslt 如下所示:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="xml" encoding="UTF-8" indent="yes" />
<xsl:strip-space elements="*" />
<xsl:template name="full">
<xsl:param name="enode" />
<xsl:for-each select="/">
<xsl:if test="*[not($enode = current())]">
<xsl:copy-of select="current()" />
</xsl:if>
</xsl:for-each>
</xsl:template>
<xsl:template match="extras">
<xsl:for-each select="//extra">
<xsl:result-document href="extra{position()}.xml">
<xsl:call-template name="full">
<xsl:with-param name="enode" select="current()" />
</xsl:call-template>
<extras>
<xsl:copy-of select="current()" />
</extras>
</xsl:result-document>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
我能够生成仅包含一个 <extra>
元素的输出 xmls,但是如何从输入中复制其余元素(即:
<extras>
的子元素除外的所有元素?)
我试图创建一个模板 "full",它循环遍历所有节点并仅复制那些与我作为参数传递的节点 (enode) 不同的节点,但没有成功。
是否有任何(其他)方法可以获得所需的结果?
如果生成的 xml 中元素的顺序与我提供的不同,这不是问题,我可以在第二遍中重新排列它们。
能不能简单点:
XSLT 2.0
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:output method="xml" encoding="UTF-8" indent="yes" />
<xsl:strip-space elements="*" />
<xsl:template match="/car">
<xsl:for-each select="extras/extra">
<xsl:result-document href="extra{position()}.xml">
<car xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<extras>
<xsl:copy-of select="*"/>
</extras>
<xsl:copy-of select="../../(* except extras)"/>
</car>
</xsl:result-document>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>