1

我在编写 C# 脚本时遇到问题,该脚本将为我提供给定子元素的某个父元素。为了清楚起见,这是 XML 树的一个示例。

<parent attribute='X'>
  <child_element1>A</child_element1>
  <child_element2 attribute='Y'>
    <grandchild_element1>B</grandchild_element1>
    <grandchild_element2>
      <key>C</key>
    </grandchild_element2>
    <grandchild_element3>D</grandchild_element3>
  </child_element2>
  <child_element3>E</child_element3>
</parent>  

遍历树,我的脚本找到了<key>节点。我想要制作的是以下树。

<parent attribute='X'>
  <child_element2 attribute='Y'>
    <grandchild_element1>B</grandchild_element1>
    <grandchild_element2>
      <key>C</key>
    </grandchild_element2>
    <grandchild_element3>D</grandchild_element3>
  </child_element2>
</parent>  

如您所见,我正在尝试删除原始树中的child_element1和。child_element3

我已经为脚本编写了一个伪代码,如下所示,但到目前为止还没有弄清楚如何在 C# 中编写真实的东西。

  1. 显示关键节点上方的所有第一个和第二个父元素。grandchild_element2是 key 的第一个父级,是 keychild_element2的第二个父级。所以他们的所有元素都显示出来了。
  2. 仅显示与下一个父级别的键有直接关系的节点/元素。parent是 key 的第三个父母。与键有直接关系的parent元素是child_element2。所以只child_element2显示。child_Element1并且child_element2没有显示,因为它们与键没有直接关系

我在 stackoverflow 上查看了以下解决方案,但不幸的是,它们都只显示了如何获取所有父元素(而不是显示<key>节点的祖先元素。

  1. 如果子节点满足特定条件,则检索 XML 父节点属性并将两者都分配给变量
  2. C# XML,找到节点和他所有的父母
4

1 回答 1

1

如果您使用 XSLT,这很容易:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes"/>
  <xsl:param name="valueToFind" select="'C'" omit-xml-declaration="yes" />

  <xsl:template match="/*">
    <xsl:apply-templates select="node()[descendant-or-self::node() = $valueToFind]" />
  </xsl:template>

  <xsl:template match="*">
    <xsl:copy>
      <xsl:copy-of select="@*"/>
      <xsl:apply-templates 
            select="node()[descendant-or-self::node() = $valueToFind]" />
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

当示例 XML 被赋予单个根元素并将其馈送到此 XSLT 中时,结果是:

<a>
  <a.1 name="First">
    <a.1.2>
      <a.1.2.2>
        <key>C</key>
      </a.1.2.2>
    </a.1.2>
  </a.1>
</a>

如果您不熟悉 XSLT,请使用 XSLT 参数:

<xsl:param name="valueToFind" select="'C'" />

本质上是一个变量,您可以从执行代码中传入其值。在这里,我刚刚为其赋予了默认值C,因此它可以在 XSLT 调试器中运行并产生可证明的结果。

于 2013-01-29T11:08:07.550 回答