我遇到的另一个问题是如何确保只有“Document”所在的“KEY”被复制到“Document”下...使用“as is”代码,XML中的所有元素复制到每个节点(同样,只有当我使用“//”运算符时)。
请帮忙。
这是我的NOT缩小结构:
<?xml version='1.0' encoding='utf-8' ?>
<Root>
<Level1>
<KEY><![CDATA[keyword1]]></KEY>
<Documents>
<Document>
<TYPE>type1</TYPE>
<IMAGE><![CDATA[string11]]></IMAGE>
</Document>
<Document>
<TYPE>type2</TYPE>
<IMAGE><![CDATA[string12]]></IMAGE>
</Document>
<Document>
<TYPE>type3</TYPE>
<IMAGE><![CDATA[string13]]></IMAGE>
</Document>
</Documents>
</Level1>
<Level1>
<KEY><![CDATA[keyword2]]></KEY>
<Documents>
<Document>
<TYPE>type1</TYPE>
<IMAGE><![CDATA[string21]]></IMAGE>
</Document>
<Document>
<TYPE>type2</TYPE>
<IMAGE><![CDATA[string22]]></IMAGE>
</Document>
<Document>
<TYPE>type3</TYPE>
<IMAGE><![CDATA[string23]]></IMAGE>
</Document>
</Documents>
</Level1>
</Root>
我想要的结果:
<?xml version='1.0' encoding='utf-8' ?>
<Root>
<Level1>
<Documents>
<Document>
<KEY><![CDATA[keyword1]]></KEY>
<TYPE>type1</TYPE>
<IMAGE><![CDATA[string11]]></IMAGE>
</Document>
<Document>
<KEY><![CDATA[keyword1]]></KEY>
<TYPE>type2</TYPE>
<IMAGE><![CDATA[string12]]></IMAGE>
</Document>
<Document>
<KEY><![CDATA[keyword1]]></KEY>
<TYPE>type3</TYPE>
<IMAGE><![CDATA[string13]]></IMAGE>
</Document>
</Documents>
</Level1>
<Level1>
<Documents>
<Document>
<KEY><![CDATA[keyword2]]></KEY>
<TYPE>type1</TYPE>
<IMAGE><![CDATA[string21]]></IMAGE>
</Document>
<Document>
<KEY><![CDATA[keyword2]]></KEY>
<TYPE>type2</TYPE>
<IMAGE><![CDATA[string22]]></IMAGE>
</Document>
<Document>
<KEY><![CDATA[keyword2]]></KEY>
<TYPE>type3</TYPE>
<IMAGE><![CDATA[string23]]></IMAGE>
</Document>
</Documents>
</Level1>
</Root>
抱歉......再次,谢谢你。
答案 0 :(得分:1)
首先,您需要阅读identity transform,看起来像这样
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
这会将所有节点复制到输出文档而不做任何更改。这意味着您只需要为需要更改的内容编写模板。
你也不应该想到移动一个元素,而是两个变化;从文档元素下删除 KEY 元素,然后添加新的 KEY 元素(即现有元素的副本)的文献强>
删除 KEY 元素非常简单。只是匹配它,什么都不做
<xsl:template match="KEY" />
在文档元素下添加新元素也很简单。您需要一个与文档元素匹配的模板,该元素与身份模板类似,但需要额外的副本,才能从父级复制 KEY 节点。
<xsl:template match="Document">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:copy-of select="../KEY" />
<xsl:apply-templates select="node()"/>
</xsl:copy>
</xsl:template>
因此,您复制文档元素,复制属性(如果有),从父级复制 KEY ,然后继续处理子节点。
这是完整的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="KEY" />
<xsl:template match="Document">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:copy-of select="../KEY" />
<xsl:apply-templates select="node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
编辑:作为替代方案,如果 KEY 不是父节点的子节点,但可以在任何深度,请尝试用此替换copy语句
<xsl:copy-of select="ancestor::*[KEY]/KEY" />
这应该处理任何级别的文档元素。
答案 1 :(得分:0)
好的,终于....这是蒂姆的原始xsl(经过微小的调整),这给了我想要的结果。蒂姆 - 再次感谢。 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 match="KEY" />
<xsl:template match="Document">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:copy-of select="../../KEY" />
<xsl:apply-templates select="node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>