简体   繁体   中英

Extracting data from the properties of an xml file

I am attempting to extract data from an xml file generated from a save function. Here is what the xml looks like when the data has been serialized

<Data> 
    <ParentID>00000000-0000-0000-0000-000000000000</ParentID> 
    <Content>&lt;ContentControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"&gt; &lt;Grid&gt;&lt;Image Source=".//Resources/Images/start.png" Tag="Start" ToolTip="Start" IsHitTestVisible="False" /&gt;&lt;/Grid&gt;&lt;/ContentControl&gt; </Content> 
</Data>

I can read the data between the <> signs using an XElement object and extract it value using Element("Child").Value for example the ParentID but I do not know how to extract the property data from within Content tags such as the programmatic reading the Tag property of the Image, in this case Tag='Start'.

Can someone please assist me to resolve this matter

If the problem you are running into is that the data in the Content node is a malformed fragment, then this is a way to extract that, fix the malformation and get at the data.

string asReadXml = @"<Data>
    <ParentID>00000000-0000-0000-0000-000000000000</ParentID>
    <Content>&lt;ContentControl xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation""&gt; &lt;Grid&gt;&lt;Image Source="".//Resources/Images/start.png"" Tag=""Start"" ToolTip=""Start"" IsHitTestVisible=""False"" /&gt;&lt;/Grid&gt;&lt;/ContentControl&gt; </Content>
</Data>";


var fragment = Regex.Match(asReadXml, @"(?:\<Content\>)(?<Xml>.+)(?:\</Content\>)", RegexOptions.ExplicitCapture).Groups["Xml"].Value;

var validFragment = Regex.Replace(Regex.Replace(fragment, "(&lt;)", "<"), "(&gt;)", ">");

var xDoc = XDocument.Parse("<Root>" + validFragment + "</Root>");

/* XDoc looks like this:

<Root>
  <ContentControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
    <Grid>
      <Image Source=".//Resources/Images/start.png" Tag="Start" ToolTip="Start" IsHitTestVisible="False" />
    </Grid>
  </ContentControl>
</Root>

*/

var Image =
   xDoc.Root
       .Descendants()
       .Where (p => p.Name.LocalName == "Image")
       .First ();

Console.WriteLine ( Image.Attribute("Tag").Value );

// Outputs
// Start
var data = @"<Data>" + 
                          "<ParentID>00000000-0000-0000-0000-000000000000</ParentID>" + 
                          "<Content>&lt;ContentControl xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"&gt;"+ 
                    "&lt;Grid&gt;&lt;Image Source=\".//Resources/Images/start.png\" Tag=\"Start\" ToolTip=\"Start\" IsHitTestVisible=\"False\" /&gt;&lt;/Grid&gt;&lt;/ContentControl&gt;" + 
                    "</Content>" + 
                    "</Data>";

        var root = XElement.Parse(data);
        var contentValue = root.Element("Content").Value; 
        var contentXml = XElement.Parse(contentValue);
        var ns = contentXml.Name.Namespace; // retrieve the namespace 
        var imageTagValue = contentXml.Element(ns+"Grid").Element(ns+"Image").Attribute("Tag").Value; // 

Assume that element is an XElement object that represent <Content> element (You already have a way to get it though), you can do as follow to get Tag attribute value of Image element :

XElement element = ....;

var content = XElement.Parse((string)element);
var ns = content.Name.Namespace;
var image = content.Descendants(ns + "Image").FirstOrDefault();
var tag = "";
if(image != null)
{
    tag = (string)image.Attribute("Tag");
}

We check if image is null before looking for it's attribute. With that, you won't get exception if there any <Content> element that doesn't have <Image> element). tag variable will simply contains empty string in that case.

This also handle case when <Content> has <Image> element resides in different path (not under <Grid> element).

Personally, I would recommend getting the whole content as a string, and then parse it as a html data using http://htmlagilitypack.codeplex.com/ library. That way you'll offload all the parsing to specialized libraries.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM