Reputation: 53
I'm having problems writing a C# script that'll get me a certain parent element of a given child element. To clear things up, this is an example of the XML tree.
<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>
Traversing the tree, my script has found the <key>
node. What I'm trying to produce is the following tree.
<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>
As you can see, I'm trying to remove child_element1
and child_element3
in original tree.
I've written a pseudo-code for the script as follows, but so far have failed to figure out how to script the real thing in C#.
grandchild_element2
is first parent of key and child_element2
is second parent of key. So all their elements are shown.parent
is third parent of key. The parent
element that has direct relation with key is child_element2
. So only child_element2
is shown. child_Element1
and child_element2
are not shown because they do not have direct relation with the keyI've taken a look at the following solutions on stackoverflow, but unfortunately they all only show how to get all parent elements (instead of showing the ones which are ancestors of the <key>
node.
Upvotes: 1
Views: 948
Reputation: 101652
This is quite easy if you use an 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>
When the example XML is given a single root element and fed into this XSLT, the result is:
<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>
In case you're unfamiliar with XSLT, an XSLT parameter:
<xsl:param name="valueToFind" select="'C'" />
is essentially a variable whose value you can pass in from the executing code. Here, I've just given it it the default value C
, so it can be run in an XSLT debugger and produce a demonstrable result.
Upvotes: 1