Linq2Xml Remove specific attribute name and their values - c#

I have this XML, and i am trying to delete those:
Name="items"
Name="shipmentsShipmentIndex"
"Name" is not going to change,
The word that will be change is the word between the quotation marks, in this example:
items and shipmentsShipmentIndex
<?xml version="1.0" encoding="UTF-8"?>
<RootDTO xmlns:json='http://james.newtonking.com/projects/json'>
<destination>
<name>XXX</name>
</destination>
<orderData>
<items json:Array='true'>
<shipmentIndex Name="items">0</shipmentIndex>
</items>
<items json:Array='true'>
<shipmentIndex Name="items">0</shipmentIndex>
</items>
<shipments json:Array='true'>
<shipmentIndex Name="shipmentsShipmentIndex">0</shipmentIndex>
</shipments>
</orderData>
</RootDTO>
How can i find all these occurrences and remove them(or replace them with nothing)?
I tried a bunch of variations like: Name{1}[a-zA-Z]+"\b

You wrote this is ASP.NET. You can use Linq2Xml to perform this operation very quickly (LinqPad example):
void Main()
{
var test = XDocument.Parse("<root><node name=\"name value\">Text</node></root>");
foreach(var attr in test.Descendants().SelectMany(el=>el.Attributes("name")))
attr.Remove();
test.Dump();
}
So from this:
<root>
<node name="name value">Text</node>
</root>
You get this:
<root>
<node>Text</node>
</root>
The snippet will remove ALL name attributes from every single element in the XML aside of the root one. If you want to do something else (like just empty the attribute, or include the root element), let me know.

Don't parse XML with regular expressions. Use an XML aware tool.
For example, in xsh, you can achieve this with
open file.xml ;
rm //#Name ;
save :b ;

Try this RegEx:
Name=\"(.*?)\"

Related

How to parse a XML with nested XML text

Trying to read XML file with nested XML object with own XML declaration. As expected got exception:
Unexpected XML declaration. The XML declaration must be the first node in the document, and no white space characters are allowed to appear before it.
How can i read that specific element as text and parse it as separate XML document for later deserialization?
<?xml version="1.0" encoding="UTF-8"?>
<Data>
<Items>
<Item>
<Target type="System.String">Some target</Target>
<Content type="System.String"><?xml version="1.0" encoding="utf-8"?><Data><Items><Item><surname type="System.String">Some Surname</surname><name type="System.String">Some Name</name></Item></Items></Data></Content>
</Item>
</Items>
</Data>
Every approach i'm trying fail due to declaration exception.
var xml = System.IO.File.ReadAllText("Info.xml");
var xDoc = XDocument.Parse(xml); // Exception
var xmlDoc = new XmlDocument();
xmlDoc.LoadXml(xml); // Exception
var xmlReader = XmlReader.Create(new StringReader(xml));
xmlReader.ReadToFollowing("Content"); // Exception
I have no control over XML creation.
The only way I would know is by getting rid of the illegal second <?xml> declaration. I wrote a sample that will simply look for and discard the second <?xml>. After that the string has become valid XML and can be parsed. You may need to tweak it a bit to make it work for your exact scenario.
Code:
using System;
using System.Xml;
public class Program
{
public static void Main()
{
var badXML = #"<?xml version=""1.0"" encoding=""UTF-8""?>
<Data>
<Items>
<Item>
<Target type=""System.String"">Some target</Target>
<Content type=""System.String""><?xml version=""1.0"" encoding=""utf-8""?><Data><Items><Item><surname type=""System.String"">Some Surname</surname><name type=""System.String"">Some Name</name></Item></Items></Data></Content>
</Item>
</Items>
</Data>";
var goodXML = badXML.Replace(#"<Content type=""System.String""><?xml version=""1.0"" encoding=""utf-8""?>"
, #"<Content type=""System.String"">");
var xmlDoc = new XmlDocument();
xmlDoc.LoadXml(goodXML);
XmlNodeList itemRefList = xmlDoc.GetElementsByTagName("Content");
foreach (XmlNode xn in itemRefList)
{
Console.WriteLine(xn.InnerXml);
}
}
}
Output:
<Data><Items><Item><surname type="System.String">Some Surname</surname><name type="System.String">Some Name</name></Item></Items></Data>
Working DotNetFiddle: https://dotnetfiddle.net/ShmZCy
Perhaps needless to say: all of this would not have been needed if the thing that created this invalid XML would have applied the common rule to wrap the nested XML in a <![CDATA[ .... ]]> block.
The <?xml ...?> processing declaration is only valid on the first line of an XML document, and so the XML that you've been given isn't well-formed XML. This will make it quite difficult to parse as is without either changing the source document (and you've indicated that's not possible) or preprocessing the source.
You could try:
Stripping out the <?xml ?> instruction with regex or string manipulation, but the cure there may be worse than the disease.
The HTMLAgilityPack, which implements a more forgiving parser, may work with an XML document
Other than that, the producer of the document should look to produce well-formed XML:
CDATA sections can help this, but be aware that CDATA can't contain the ]]> end tag.
XML escaping the XML text can work fine; that is, use the standard routines to turn < into < and so forth.
XML namespaces can also help here, but they can be daunting in the beginning.

how to extract attribute from tag xml with c#?

<channel>
<title>test + test</title>
<link>http://testprog.test.net/api/test</link>
<description>test.com</description>
<category>test + test</category>
<item xml:base="http://test.com/test.html?id=25>
<guid isPermaLink="false">25</guid>
<link>http://test.com/link.html</link>
<title>title test</title>
<description>Description test description test</description>
<a10:updated>2015-05-26T10:23:53Z</a10:updated>
<enclosure type="" url="http://test.com/test/test.jpg" width="200" height="200"/>
</item>
</channel>
I extracted this tag (title test) like this:
title = ds.Tables["item"].Rows[0]["title"] as string;
how to extract url attribute from <encosure> tag with c#?
thx
First option
You can create classes to map and deserialize the XML into object and easily access as properties.
Second option
If you are only interested in few values and you don't want to create mapping classes , you can use XPath, there are many articles and questions anwered that you can easily find.
To extract url attribute from tag you can use the path:
"/channel/item/enclosure/param[#name='url']/#value"
There are many, many articles that will help you read XML, but the simple answer is to load your XML into an XML document, and simply call
doc.GetElementsByTagName("enclosure")
This will return an XmlNodeList with all 'enclosure' tags found in your document. I would really recommend doing some reading about using XML to make sure your application is functional and robust.
You can use LinqToXML and this will be better useful for you...
please refer the code
string xml = #"<channel>
<title>test + test</title>
<link>http://testprog.test.net/api/test</link>
<description>test.com</description>
<category>test + test</category>
<item xml:base=""http://test.com/test.html?id=25"">
<guid isPermaLink=""false"">25</guid>
<link>http://test.com/link.html</link>
<title>title test</title>
<description>Description test description test</description>
<a10>2015-05-26T10:23:53Z</a10>
<enclosure type="""" url=""http://anupshah.com/test/test.jpg"" width=""200"" height=""200""/>
</item>
</channel>";
var str = XElement.Parse(xml);
var result = (from myConfig in str.Elements("item")
select myConfig.Elements("enclosure").Attributes("url").SingleOrDefault())
.First();
Console.WriteLine(result.ToString());
I hope it will help you...

XML select sing node and loop through it

I'm having some issues looping through an XML node.
To begin, here is the general format of the XML file:
<Config>
<Facilities>
<Facility>
<ID>1</ID>
<Name>Facility Name</Name>
<Profiles>
<Profile>
<Name>Value</Name>
<Item2>Value</2>
</Profile>
<Profile>
<Name>Another Value</Name>
</Profile>
</Profiles>
</Facility>
<Facility>
<ID>2</ID>
<Name>Facility Name</Name>
<Profiles>
<Profile>
<Name>Value</Name>
</Profile>
</Profiles>
</Facility>
</Facilities>
</Config>
And here's the code I'm using:
XmlDocument configFile = new XmlDocument();
configFile.Load(CONFIG_FILE);
XmlNodeList nodeList = configFile.SelectNodes("/Config/Facilities/Facility[ID[text()='" + facilityID + "']]/Profiles/Profile");
foreach (XmlNode no in nodeList)
{
Console.WriteLine(no["Name"].InnerText);
//myList.Items.Add(no["Name"].InnerText);
}
Basically, I want to loop through the facilities and select the facility with a specific ID (this id is derived from the facilityID that I set earlier in my code...and yes I've checked, it's being set correctly). I then want to go through the profiles associated with the facility and loop through them. I want to be able to take all the elements in each <Profile> as applicable.
However, when I execute this code, it's not returning anything in the debug console.
I'm not sure if this is exists in your file, but there appears to be XML errors in the example posted.
<Item2>Value</2>
If I remove that, I'm able to correctly see the value expected. For example, if I use a value of "1" for facilityID, I receive
Value
Another Value
You mean something like this? This is using the XElement class, of course. I tend to prefer it because it's easier to debug and, at least for me, easier to deploy.
var root = XElement.Load(CONFIG_FILE).Element("Facilities");
var facility = root.Elements("Facility").FirstOrDefault(c => c.Element("ID").Value == facilityID.ToString());
return facility.Element("Profiles").Elements("Profile");
It doesn't have any error handling, but you can add that in as necessary.
I don't know if you want to do this or not, it depends how you'll be using it, but you could also replace the last line there with this:
return facility.Element("Profiles").Elements("Profile").Select(c => c.Element("Name").Value);
And that would give you just the names. Again, depends on what exactly you're looking for. I just added this since I see your example is only printing out the names.

Change an XML node value

I have an xml document that looks like this
<?xml version="1.0"?>
<XML>
<VIDEO>
<WIDTH>800</WIDTH>
<HEIGHT>600</HEIGHT>
<COLORBITS>32</COLORBITS>
<GAMMA>255</GAMMA>
<FULLSCREEN>TRUE</FULLSCREEN>
<REFLECTION>true</REFLECTION>
<LIGHTMAP>true</LIGHTMAP>
<DYNAMICLIGHT>true</DYNAMICLIGHT>
<SHADER>true</SHADER>
<CHARACTORTEXTURELEVEL>0</CHARACTORTEXTURELEVEL>
<MAPTEXTURELEVEL>0</MAPTEXTURELEVEL>
<EFFECTLEVEL>0</EFFECTLEVEL>
<TEXTUREFORMAT>1</TEXTUREFORMAT>
<NHARDWARETNL>false</NHARDWARETNL>
</VIDEO>
</XML>
I want to change the value of the "MAPTEXTURELEVEL" node from 0 to 6 using the checked statement of a checkbox in a C# application, but I really have no idea of how I can do it.
I don't have VS to test it, but it should be something like this using LINQ to XML:
var doc = XDocument.Load("video.xml");
doc
.Element("XML")
.Element("VIDEO")
.SetElementValue("MAPTEXTURELEVEL", 6);
doc.Save("video_modified.xml");
Hope it helps!

How to get attribute in the XDocument object

I have this xml
<config>
<audio first="true" second="false" third="true" />
</config>
I want my code to able to do something like this
if (xdoc.getAttr("first")=="true")
Console.Write("first is true");
How do I do this with LINQ XDocument?
What I have so far is the XDocument Object loaded with that xml string.
You need to get the attribute of the <audio> element:
string value = xdoc.Root.Element("audio").Attribute("first").Value;
You should take a look at XElement
article at c-sharpcorner.com

Categories