将包含子节点列表的xml转换为单独的xml
我有一个包含xml子节点列表的xml输入。我想根据xml子节点分离此xml。但在分离时,需要保留父节点。我试着使用for-each,但输出并不像预期的那样 输入 预期产量将包含子节点列表的xml转换为单独的xml,xml,xslt,Xml,Xslt,我有一个包含xml子节点列表的xml输入。我想根据xml子节点分离此xml。但在分离时,需要保留父节点。我试着使用for-each,但输出并不像预期的那样 输入 预期产量 <node1> <id>1</id> <code>abcd</code> <version>v1</version> <node2> <market>india</market&
<node1>
<id>1</id>
<code>abcd</code>
<version>v1</version>
<node2>
<market>india</market>
<active>true</active>
</node2>
<mixins>
<node3>
<ref>MZ-SR-P004</ref>
<type>Commercial</type>
</node3>
</mixins>
</node1>
<node1>
<id>1</id>
<code>abcd</code>
<version>v1</version>
<node2>
<market>US</market>
<active>true</active>
</node2>
<mixins>
<node3>
<ref>MZ-SR-P004</ref>
<type>Commercial</type>
</node3>
</mixins>
</node1>
是否可以使用xslt实现这一点。我尝试了下面的XSLT转换
XSLT
在模板匹配
node2
中,然后执行xsl:for each
以选择node2
,但这将查找当前匹配的node2
的子元素,因此不会选择任何内容
您的模板可能应该选择node1
。然后,在xsl:for each
中,需要创建node1
并复制当前node2
或其他命名节点的所有子节点
试试这个XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="node1">
<xsl:for-each select="node2">
<node1>
<xsl:apply-templates select="../*[generate-id() = generate-id(current()) or not(self::node2)]" />
</node1>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
注意,我还从标识模板中删除了
。在模板匹配node2
中,然后对每个执行xsl:for-each
以选择node2
,但这将查找当前匹配的node2
的子元素,因此不会选择任何内容
您的模板可能应该选择node1
。然后,在xsl:for each
中,需要创建node1
并复制当前node2
或其他命名节点的所有子节点
试试这个XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="node1">
<xsl:for-each select="node2">
<node1>
<xsl:apply-templates select="../*[generate-id() = generate-id(current()) or not(self::node2)]" />
</node1>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
注:我还从标识模板中删除了
。更通用的XSLT 2或3方法是选择节点(例如node1/node2
)然后通过一个模式推送完整的树,使用存储当前node2
的隧道参数进行身份复制,以确保当该模式在node2
上匹配时,它只输出该特定的node2
,而忽略所有其他模式:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
version="3.0">
<xsl:mode on-no-match="shallow-copy"/>
<xsl:mode name="reconstruct" on-no-match="shallow-copy"/>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<xsl:for-each select="node1/node2">
<xsl:apply-templates select="/" mode="reconstruct">
<xsl:with-param name="copy" tunnel="yes" select="current()"/>
</xsl:apply-templates>
</xsl:for-each>
</xsl:template>
<xsl:template match="node2" mode="reconstruct">
<xsl:param name="copy" tunnel="yes"/>
<xsl:sequence select=".[. is $copy]"/>
</xsl:template>
</xsl:stylesheet>
更通用的XSLT2或3方法是选择节点(例如,node1/node2
)然后通过一个模式推送完整的树,使用存储当前node2
的隧道参数进行身份复制,以确保当该模式在node2
上匹配时,它只输出该特定的node2
,而忽略所有其他模式:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
version="3.0">
<xsl:mode on-no-match="shallow-copy"/>
<xsl:mode name="reconstruct" on-no-match="shallow-copy"/>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<xsl:for-each select="node1/node2">
<xsl:apply-templates select="/" mode="reconstruct">
<xsl:with-param name="copy" tunnel="yes" select="current()"/>
</xsl:apply-templates>
</xsl:for-each>
</xsl:template>
<xsl:template match="node2" mode="reconstruct">
<xsl:param name="copy" tunnel="yes"/>
<xsl:sequence select=".[. is $copy]"/>
</xsl:template>
</xsl:stylesheet>
您能否向我们展示您现在的输出,以及您想要的输出?您能否向我们展示您当前使用xsl:for each
的尝试。它可能不起作用,但实际上你可能并不遥远。谢谢,这是我试过的。请编辑问题,而不是在注释中添加代码。使用更多信息编辑问题。您能否向我们展示您现在的输出,以及您想要的输出?您能否向我们展示您当前使用xsl:for each
的尝试。它可能不起作用,但实际上你可能并不遥远。谢谢,这是我试过的。请编辑问题,而不是在注释中添加代码。请使用详细信息编辑问题
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
version="3.0">
<xsl:mode on-no-match="shallow-copy"/>
<xsl:mode name="reconstruct" on-no-match="shallow-copy"/>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<xsl:for-each select="node1/node2">
<xsl:apply-templates select="/" mode="reconstruct">
<xsl:with-param name="copy" tunnel="yes" select="current()"/>
</xsl:apply-templates>
</xsl:for-each>
</xsl:template>
<xsl:template match="node2" mode="reconstruct">
<xsl:param name="copy" tunnel="yes"/>
<xsl:sequence select=".[. is $copy]"/>
</xsl:template>
</xsl:stylesheet>