【问题标题】:XSLT XML to XML selecting specific nodeXSLT XML 到 XML 选择特定节点
【发布时间】:2012-08-09 13:46:14
【问题描述】:

我正在尝试通过 XSLT 将一个非常复杂的 XML 文件转换为 XML,因此它将是前一个 XML 文档的副本,仅在输出中排除了第二个孙节点。希望有一个使用 XSLT 的简单解决方案。

这是我尝试转换的 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>

任何帮助将不胜感激。

【问题讨论】:

  • 您选择的答案是错误的——它删除了第一个,而不是第二个Grandchild_node。 @TimC 的答案是正确的。请接受正确的答案。
  • @DimitreNovaatchev,他评论说他正在尝试删除特定的唯一节点。我已经更新了我的答案,使其更加清晰。
  • @DerekHunziker,是的,我看到一个更正。但是,您还指的是不存在的Grandchild_node[5] - 这不是很奇怪吗?
  • 为什么这么奇怪?这是一个示例,就像提供的 XML 源一样。重点显然是演示一种技术,而不是为特定的输入文档提供特定的解决方案,这显然是不可能仅使用示例 XML 文档实现的。

标签: xml xslt


【解决方案1】:

您应该能够将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>

由于您评论说要删除一些单独的unique child_nodes,您可以将它们包含在此列表中。 Tim 使用 position() 的解决方案非常适合排除范围。

【讨论】:

  • 我应用了这个并且输出是空白的。我应该提一下,有一些单独的独特 child_nodes 我没有提到我也想加入。不知道我是否需要根据他们的存在来修改任何内容。
【解决方案2】:

这可以通过向身份转换添加额外的模板匹配来实现,以简单地匹配不在第一个位置的 Grandchild_node 元素

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

所以,给定以下 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>

当应用于您的示例 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>

【讨论】:

  • 我应用了这个并且输出是空白的。我应该提一下,有一些单独的独特 child_nodes 我没有提到我也想加入。不知道我是否需要根据他们的存在来修改任何内容。
  • 忽略之前的评论,工作,没有先重新保存 XSLT 文件。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多