2012-08-08 169 views
0

我试图通过XSLT到相当复杂的XML文件转换为XML,因此将只排除在输出的第二孙节点之前的XML文档的副本。希望使用XSLT有一个简单的解决方案。XSLT XML到XML选择特定节点

这里是XML我想改变的一个样本:

<cases> 
    <Parent> 
     <text1>Text1</text1> 
     <text2>Text2</text2> 
     <text3>Text3</text3> 
     <Child_node> 
      <Grandchild_node> 
       <gctext1>Sample text 1</gctext1> 
       <gctext2>Sample text 2</gctext2> 
       <gctext3>Sample text 3</gctext3> 
       <Great_grandchild_node> 
        <ggctext1>Great grandchild text 1</ggctext1> 
       </Great_grandchild_node> 
      </Grandchild_node> 
      <Grandchild_node> 
       <gctext1>More Sample text 1</gctext1> 
       <gctext2>Different Sample text 2</gctext2> 
       <gctext3>More Sample text 3</gctext3> 
       <Great_grandchild_node> 
        <ggctext1>Great grandchild text 2</ggctext1> 
       </Great_grandchild_node> 
      </Grandchild_node> 
     </Child_node> 
    </Parent> 
</cases> 

我要输出到显示一切,但包含在第二Grandchild_node的信息。输出示例我想实现:

<cases> 
    <Parent> 
     <text1>Text1</text1> 
     <text2>Text2</text2> 
     <text3>Text3</text3> 
     <Child_node> 
      <Grandchild_node> 
       <gctext1>Sample text 1</gctext1> 
       <gctext2>Sample text 2</gctext2> 
       <gctext3>Sample text 3</gctext3> 
       <Great_grandchild_node> 
        <ggctext1>Great grandchild text 1</ggctext1> 
       </Great_grandchild_node> 
      </Grandchild_node> 
     </Child_node> 
    </Parent> 
</cases> 

任何帮助,将不胜感激。

+0

您选择的答案是错误的 - 它删除第一,没有第二个'Grandchild_node'。 @TimC的答案是正确的。请接受正确的答案。 – 2012-08-09 01:28:24

+0

@DimitreNovatchev,他评论说,他试图删除特定的独特节点。我已经更新了我的答案,以便更清楚一点。 – 2012-08-09 05:38:45

+0

@DerekHunziker,是的,我看到一个更正。但是你也指的是不存在的'祖孙节点[5]' - 这不是奇怪的吗? – 2012-08-09 11:53:46

回答

2

你应该能够结合使用xsl:copy相匹配的任何节点上,您想删除:

<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/> 
     </xsl:copy> 
    </xsl:template> 
    <xsl:template match="Grandchild_node[2]|Grandchild_node[5]"></xsl:template> 
</xsl:stylesheet> 

既然你评论说,有要删除一些单独独特 child_nodes,您可以包括那些在这个列表中。 Tim的使用position()的解决方案很适合排除范围。

+0

我应用了这个,输出是空白的。我应该提到,有一些独立的独特child_nodes,我没有提到我也想过来。不知道我是否需要根据他们的存在来修改任何东西。 – user1585862 2012-08-08 22:34:38

+0

无视事先评论。这似乎工作。谢谢! – user1585862 2012-08-08 22:41:36

2

这可以通过增加一个额外的模板匹配的身份来实现转化为简单的搭配,考虑到下面的XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" indent="yes"/> 

    <xsl:template match="Grandchild_node[position() > 1]" /> 

    <xsl:template match="@*|node()"> 
     <xsl:copy> 
     <xsl:apply-templates select="@*|node()"/> 
     </xsl:copy> 
    </xsl:template> 
</xsl:stylesheet> 
Grandchild_node元素不在第一位置

<xsl:template match="Grandchild_node[position() > 1]" /> 

所以

当应用于您的示例XML时,输出如下内容

<cases> 
    <Parent> 
     <text1>Text1</text1> 
     <text2>Text2</text2> 
     <text3>Text3</text3> 
     <Child_node> 
     <Grandchild_node> 
      <gctext1>Sample text 1</gctext1> 
      <gctext2>Sample text 2</gctext2> 
      <gctext3>Sample text 3</gctext3> 
      <Great_grandchild_node> 
       <ggctext1>Great grandchild text 1</ggctext1> 
      </Great_grandchild_node> 
     </Grandchild_node> 
     </Child_node> 
    </Parent> 
</cases> 
+0

我应用了这个,输出是空白的。我应该提到,有一些独立的独特child_nodes,我没有提到我也想过来。不知道我是否需要根据他们的存在来修改任何东西。 – user1585862 2012-08-08 22:34:14

+0

无视之前的评论,作品,没有首先重新保存XSLT文件。谢谢。 – user1585862 2012-08-08 22:42:04