0

In C# I'm using the following to get some elements from an XML file:

var TestCaseDescriptions = doc.SelectNodes("//testcase/htmlcomment");

This works fine and gets the correct information but when my testcase has no htmlcomment it won't add any entry in the XmlNodeList TestCaseDescriptions.

When there's not htmlcomment I would like to have the value "null" as string the TestCaseDescriptions. So in the end I would have an XMLNodeList like

htmlcomment

htmlcomment

null

htmlcomment

htmlcomment

Can anyone describe or create a sample how to make this happen?

2 Answers 2

1
var TestCaseDescriptions = doc.SelectNodes("//testcase/htmlcomment");

When there's not htmlcomment I would like to have the value "null" as string the TestCaseDescriptions.

Your problem comes from the fact that if there is no htmlcomment, the number of selected nodes will be one less. The current answer shows what to do when the htmlcomment element is present, but empty, but I think you need this instead, if indeed the whole htmlcomment element is empty:

var testCases = doc.SelectNodes("//testcase");
foreach (XmlElement element in testCases)
{
    var description = element.SelectSingleNode("child::htmlcomment");
    string results = description == null ? "null" : description.Value;
}​

In above code, you go over each test case, and select the child node htmlcomment of the test case. If not found, SelectSingleNode returns null, so the last line checks for the result and returns "null" in that case, or the node's value otherwise.

To change this result into a node, you will have to create the node as a child to the current node. You said you want an XmlNodeList, so perhaps this works for you:

var testCaseDescriptions = doc.SelectNodes("//testcase");
foreach (XmlElement element in testCaseDescriptions)
{
    var comment = element.SelectSingleNode("child::htmlcomment");
    if (comment == null)
    {
        element.AppendChild(
            doc.CreateElement("htmlcomment")
            .AppendChild(doc.CreateTextNode("none")));
    }
}​

After this, the node set is updated.


Note: apparently, the OP mentions that element.SelectSingleNode("child::htmlcomment"); does not work, but element.SelectSingleNode("./htmlcomment"); does, even though technically, these are equal expressions from the point of XPath, and should work according to Microsoft's documentation.

Sign up to request clarification or add additional context in comments.

6 Comments

Thanks for your answer! I managed to get the result I wanted (using the second snippet), I only had to change the parameter for SelectSingleNode as it did not give any results. I changed it into: var comment = element.SelectSingleNode(@"./htmlcomment");
@Nicholas, that should have the same effect (. merely means current node and is typically a no-op at the beginning of an XPath expression). This may be a bug in the implementation from Microsoft (though I'm surprised). Glad it works!
I just saw that the 1st htmlcomment contains all the texts of the other htmlcomments while it also doesn't exist and should be "none". Other entries are fine and returning "none" if it's needed but only the 1st record/node is not ok. Any ideas why this only happens to the 1st one?
@Nicholas, that sounds odd, but try replacing ./htmlcomment with ./htmlcomment[1] to force selecting one node. You can also serialize the content (or debug and hover over it) to find what the selected node really looks like.
Tried that but it doesn't help.
|
0

Try this

XmlDocument doc = new XmlDocument();
var TestCaseDescriptions = doc.SelectNodes("//testcase/htmlcomment");
foreach (XmlElement element in TestCaseDescriptions)
{
    string results = element.Value == null ? "" : element.Value;
}​

3 Comments

Thanks for your answer but at first it did not return anything. I changed the condition to be element.InnerText == "" ? "Nothing" : element.InnerText; and now it returns the InnerText when there's one but it does not print "Nothing" when the element is missing.
Btw it seems that Value is always null. When I change the condition to element.Value = null it will print Nothing. ( string results = element.Value == null ? "Nothing" : element.InnerText; )
Try this : string results = element.Value.Length == 0 ? "Null" : element.InnerText;

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.