Delete multiple XML nodes in C# using Linq - c#

I'm trying to remove multiple nodes that a particular element(path) contains a value but I'm receiving a System.NullReferenceException any help where I'm going wrong would I'be much appreciated.
My xml looks like this:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<ApplicationData Version="12.5.1" RootPath="FireFox-FILES">
<RegistrySystem>
<DIR Operation="+" Path="C:\Temp\Microsoft\MediaPlayer\ShimInclusionList" />
<DIR Operation="+" Path="C:\Temp\MediaPlayer\ShimInclusionList\MM.EXE" />
<DIR Operation="+" Path="C:\Temp\MediaPlayer\ShimInclusionList\plugin-container.exe" />
<DIR Operation="+" Path="C:\Temp\Microsoft\MediaPlayer">
<ENTRY Name="" Value="43.0.4" Type="1" />
<ENTRY Name="CurrentVersion" Value="43.0.4 (x86 en-GB)" Type="1" />
</DIR>
<DIR Operation="+" Path="C:\Program Files\Microsoft\MediaPlayer\ShimInclusionList\plugin-container.exe" />
<DIR Operation="+" Path="C:\Program Files\Microsoft\MediaPlayer\ShimInclusionList2\plugin.exe" />
<DIR Operation="+" Path="C:\Program Files\Microsoft\MediaPlayer\ShimInclusionList2\container.exe" />
<DIR Operation="+" Path="C:\Program Files\Microsoft\MediaPlayer\ShimInclusionList4">
<ENTRY Name="" Value="43.0.4" Type="1" />
<ENTRY Name="CurrentVersion" Value="43.0.4 (x86 en-GB)" Type="1" />
</DIR>
</RegistrySystem>
</ApplicationData>
My code looks like this:
XDocument xdoc = XDocument.Load(XmlFile);
foreach (var node in xdoc.Descendants("DIR").Where(status => status.Attribute("Path").Value.Contains(#"C:\Temp\")))
{
node.Remove();
}
xdoc.Save(XmlFile);
I'm not sure where I'm going wrong.

I'm not sure why you're getting the exception, but I strongly suspect it's because you're modifying the document while you're querying it.
If you change your code to use a ToList() call to get the list of nodes to remove, that doesn't throw:
foreach (var node in xdoc.Descendants("DIR")
.Where(status => status.Attribute("Path").Value.Contains(#"C:\Temp\"))
.ToList())
{
node.Remove();
}
However, that's not the best way. The best approach is to use the Remove(this IEnumerable<XElement>) extension method:
xdoc.Descendants("DIR")
.Where(status => status.Attribute("Path").Value.Contains(#"C:\Temp\"))
.Remove();
No need for a foreach loop at all. Now to make it robust in the face of DIR elements without a Path attribute, you can cast to string instead:
xdoc.Descendants("DIR")
.Where(status => ((string) status.Attribute("Path") ?? "").Contains(#"C:\Temp\"))
.Remove();

Related

Tizen.NET NfcCardEmulation throws UnsupportedException (with added privileges)

I had a issue with a Tizen.NET Api v4. Generally i need cardemulation in the watch, but while executing static method
NfcManager.GetCardEmulationAdapter()
i am gettings logs
tizen-manifest.xml looks like (and he was generating by vs2019 with Tizen ext)
<?xml version="1.0" encoding="utf-8"?>
<manifest package="tizenapp" version="1.0.1" api-version="4" xmlns="http://tizen.org/ns/packages">
<profile name="wearable" />
<ui-application appid="tizenapp" exec="tizenapp.dll" multiple="false" nodisplay="false" taskmanage="true" type="dotnet" launch_mode="single">
<label>tizenapp</label>
<icon>tizenapp.png</icon>
<metadata key="http://tizen.org/metadata/prefer_dotnet_aot" value="true" />
<splash-screens />
</ui-application>
<shortcut-list />
<privileges>
<privilege>http://tizen.org/privilege/secureelement</privilege>
<privilege>http://tizen.org/privilege/nfc</privilege>
<privilege>http://tizen.org/privilege/nfc.cardemulation</privilege>
<privilege>http://tizen.org/feature/network.nfc.card_emulation</privilege>
<privilege>http://tizen.org/feature/network.nfc</privilege>
</privileges>
<dependencies />
<provides-appdefined-privileges />
<feature name="http://tizen.org/feature/network.nfc">true</feature>
<feature name="http://tizen.org/feature/network.nfc.card_emulation">true</feature>
<feature name="http://tizen.org/feature/network.secure_element">true</feature>
<feature name="http://tizen.org/feature/network.secure_element.ese">true</feature>
<feature name="http://tizen.org/feature/network.secure_element.uicc">true</feature>
</manifest>
I dont know what i need to fix this problems.
It looks like a simple typo in the implementation. It's fixed in API5 and later.
https://github.com/Samsung/TizenFX/pull/578/files
I'm not sure if there's any workaround for this when targetting for API4, because it's not about a privilege but a feature.

keep getting ERR.SWS.CLIENT.VALIDATION_FAILED exception when calling PassengerDetailsRQ

I am using Sabre SOAP Api in C#. I got the response from session creation successfully, I added wsdl Service Reference
http://files.developer.sabre.com/wsdl/sabreXML1.0.00/ServicesPlatform/PassengerDetails3.3.0RQ.wsdl to my test project and pass required values to parameters in the request as given in the documentation https://developer.sabre.com/docs/read/soap_apis/management/itinerary/Passenger_Details.
this is my xml to that is send to sabre and Getting Exception
<?xml version="1.0" encoding="utf-16"?>
<PassengerDetailsRQ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" version="2.2.1"
IgnoreOnError="false">
<MiscSegmentSellRQ xmlns="http://services.sabre.com/sp/pd/v3_2">
<MiscSegment DepartureDateTime="2018-01-10T16:45" InsertAfter="0" NumberInParty="1" Status="HK" Type="OTH">
<OriginLocation LocationCode="SAN" />
<Text>America Tours</Text>
<VendorPrefs>
<Airline Code="DL" />
</VendorPrefs>
</MiscSegment>
</MiscSegmentSellRQ>
<PostProcessing xmlns="http://services.sabre.com/sp/pd/v3_2">
<EndTransactionRQ>
<EndTransaction Ind="true">
<Email Ind="true" />
</EndTransaction>
<Source ReceivedFrom="SWS TESTING" />
</EndTransactionRQ>
</PostProcessing>
<PreProcessing xmlns="http://services.sabre.com/sp/pd/v3_2" />
<PriceQuoteInfo xmlns="http://services.sabre.com/sp/pd/v3_2">
<Link NameNumber="1.1" Record="1" />
</PriceQuoteInfo>
<SpecialReqDetails xmlns="http://services.sabre.com/sp/pd/v3_2">
<SpecialServiceRQ>
<SpecialServiceInfo>
<SecureFlight>
<PersonName DateOfBirth="02/02/1998" NameNumber="1.1">
<GivenName>Usama QW</GivenName>
<Surname>Alam</Surname>
</PersonName>
<VendorPrefs>
<Airline />
</VendorPrefs>
</SecureFlight>
</SpecialServiceInfo>
</SpecialServiceRQ>
</SpecialReqDetails>
<TravelItineraryAddInfoRQ xmlns="http://services.sabre.com/sp/pd/v3_2">
<AgencyInfo>
<Address>
<AddressLine>America Tours</AddressLine>
<CityName>Los Angeles</CityName>
<CountryCode>US</CountryCode>
<PostalCode>90020</PostalCode>
<StateCountyProv StateCode="CA" />
<StreetNmbr>3434 West 6th Street Suite 400-6</StreetNmbr>
</Address>
<Ticketing TicketType="7T-A" />
</AgencyInfo>
<CustomerInfo>
<ContactNumbers>
<ContactNumber NameNumber="1.1" Phone="213-738-8185" PhoneUseType="A" />
<ContactNumber NameNumber="1.1" Phone="3162881034" PhoneUseType="A" />
</ContactNumbers>
<Email Address="www.usamaalam60#gmail.com" ShortText="AmericaTours" />
<Email Address="admin#koreaonly.com" ShortText="AmericaTours" />
<PersonName NameNumber="1.1" NameReference="MR" PassengerType="ADT">
<GivenName>Usama sd</GivenName>
<Surname>Alam</Surname>
</PersonName>
</CustomerInfo>
</TravelItineraryAddInfoRQ>
</PassengerDetailsRQ>
For this one you seem to be using invalid service version for the 3.2 namespace. Try with something like this:
*xmlns="http://services.sabre.com/sp/pd/v3_2"* and *version="3.2.0"*.
You were using version 2.2.1 here which will require a different URL.
Are you intending to use 3.2.0 version? I can see that the dates are not valid as per the schema as well. You have:
*DateOfBirth="02/02/1998"*
but should have:
*DateOfBirth="1998-02-02"*

Passing XML multi level data as parameter and using in stored procedure

I have XML format data which I will pass from a .net application.
In the SQL Server stored procedure, this data is passed in as a XML parameter. I want to read and save the data in the required tables, say TblOrder and TblItem.
In XML, there will be multiple orders. Each order contains one or several items accordingly.
Structure on which operation need to be implemented:
<?xml version="1.0" encoding="UTF-8"?>
<Orders>
<Order>
<B2>B2**ABIJ**0000884443**PP</B2>
<CreateBy null="true" />
<CreateDate>/Date(1485150414358)/</CreateDate>
<CurrencyId>1</CurrencyId>
<CustomerId>13</CustomerId>
<DeliveryAddress>LIBERTY PRESS LLC</DeliveryAddress>
<DeliveryCity>SPRINGVILLE UT 84663</DeliveryCity>
<DeliveryCityId>0</DeliveryCityId>
<DeliveryDate>/Date(1478750400000)/</DeliveryDate>
<DeliveryId>14</DeliveryId>
<DeliveryState>UT</DeliveryState>
<DeliveryStateId>16</DeliveryStateId>
<DeliveryType>Delivery</DeliveryType>
<EquipmentId>4</EquipmentId>
<Items>
<Item>
<CSA>false</CSA>
<CTPAT>false</CTPAT>
<CommodityItem>General Freight</CommodityItem>
<CommodityItemId>0</CommodityItemId>
<CustCommodityItem null="true" />
<FAST>false</FAST>
<Hazmat>false</Hazmat>
<Height null="true" />
<IsActive>false</IsActive>
<ItemId>0</ItemId>
<ItemName>Item A</ItemName>
<Length null="true" />
<Make null="true" />
<Mass null="true" />
<MassUnit null="true" />
<Model null="true" />
<OrderId>0</OrderId>
<PIP>false</PIP>
<PilotCar>false</PilotCar>
<ReeferTemp null="true" />
<Tarp>false</Tarp>
<TrailerType null="true" />
<TruckType null="true" />
<VIN null="true" />
<Width null="true" />
<Year null="true" />
</Item>
</Items>
<L11>L11*SYL884443*BM</L11>
<LastUpdate>/Date(1485150414358)/</LastUpdate>
</Order>
<Order>
...
<Items>
<Item>
...
</Item>
</Order>
</Orders>
Steps I want to achieve are:
Read XML parameter from the stored procedure, which is passed from the .net application.
Loop through the XML and save data in the TblOrder and TblItem tables
Going through the article follows :
Pass-XML-parameter-to-Stored-Procedure
How to loop and parse xml parameter in sql server stored procedure
I got the Idea to access very first level (in my case Order of Orders).
Moving forward having issue accessing the second level which will be again a collection (in my case Item of Items of Order).
Thanks in advance for your support
You have two approaches:
You can pass the XML as-is into a Stored Procedure and do all the hard work in T-SQL
You can shredd the XML within C#, fill appropriate data objects and use classical data storage.
From your question I take, that you'd prefer to pass this into a stored procedure as XML parameter. There are some things to know:
C# uses 16-bit-unicode internally and so does SQL Server's XML. But you will not be able to cast this unicode string to XML as long as there is encoding="UTF-8" included... You might pass this as VARCHAR(MAX) (not NVARCHAR(MAX)!), but this could lead you in troubles if there are sepcial characters involved. Best was, to cut the first line (the <?xml ...?> declaration) away completely.
Your XML is not created correctly. Is this under you control? If you include null="true" (there's no need for normally!), you should do this with the xsi-namespace. And date/time values within XML should be ISO8601. Your values (like /Date(1485150414358)/) are no format SQL Server will be able to cast directly...
Nevertheless I see multi <Order>-elements and multi <Item>-elements. You could read them as follows:
DECLARE #xml XML=
N'<Orders>
<Order>
<B2>B2**ABIJ**0000884443**PP</B2>
<CreateBy null="true" />
<CreateDate>/Date(1485150414358)/</CreateDate>
<CurrencyId>1</CurrencyId>
<CustomerId>13</CustomerId>
<DeliveryAddress>LIBERTY PRESS LLC</DeliveryAddress>
<DeliveryCity>SPRINGVILLE UT 84663</DeliveryCity>
<DeliveryCityId>0</DeliveryCityId>
<DeliveryDate>/Date(1478750400000)/</DeliveryDate>
<DeliveryId>14</DeliveryId>
<DeliveryState>UT</DeliveryState>
<DeliveryStateId>16</DeliveryStateId>
<DeliveryType>Delivery</DeliveryType>
<EquipmentId>4</EquipmentId>
<Items>
<Item>
<CSA>false</CSA>
<CTPAT>false</CTPAT>
<CommodityItem>General Freight</CommodityItem>
<CommodityItemId>0</CommodityItemId>
<CustCommodityItem null="true" />
<FAST>false</FAST>
<Hazmat>false</Hazmat>
<Height null="true" />
<IsActive>false</IsActive>
<ItemId>0</ItemId>
<ItemName>Item A</ItemName>
<Length null="true" />
<Make null="true" />
<Mass null="true" />
<MassUnit null="true" />
<Model null="true" />
<OrderId>0</OrderId>
<PIP>false</PIP>
<PilotCar>false</PilotCar>
<ReeferTemp null="true" />
<Tarp>false</Tarp>
<TrailerType null="true" />
<TruckType null="true" />
<VIN null="true" />
<Width null="true" />
<Year null="true" />
</Item>
</Items>
<L11>L11*SYL884443*BM</L11>
<LastUpdate>/Date(1485150414358)/</LastUpdate>
</Order>
</Orders>';
--the query
SELECT --elements of Order
o.value(N'(B2)[1]',N'nvarchar(max)') AS B2
--very strange date-format...
,o.value(N'(CreateDate)[1]',N'nvarchar(max)') AS CreateDate
--typed INT
,o.value(N'(CurrencyId)[1]',N'int') AS CurrencyId
--more like this
--elements of Item
,i.value(N'(CSA)[1]',N'nvarchar(max)') AS CSA
--There's no need for *null="true"*
--Query the "/text()" and the empty element will be NULL
,CASE WHEN i.value(N'(CustCommodityItem/#null)[1]',N'nvarchar(max)')=N'true' THEN NULL ELSE i.value(N'(CustCommodityItem)[1]',N'nvarchar(max)') END AS CustCommodityItem_complicated
,i.value(N'(CustCommodityItem)[1]',N'nvarchar(max)') AS CustCommodityItem_empty
,i.value(N'(CustCommodityItem/text())[1]',N'nvarchar(max)') AS CustCommodityItem_null
FROM #xml.nodes(N'/Orders/Order') AS A(o)
OUTER APPLY o.nodes(N'Items/Item') AS B(i)

exporting XmlDocument to excel

I have a XmlDocument in which i have hierarchical data and i want to export this data to excel. Please help me to get out of this.
I have tried to read this data into a dataset but it is not working for me.
Please send xml sample for more information.
Your code loads xml into dataset, so,
if your xml doesn't exported from DataSet, you could use LinqToXml.
for example:
xml:
<?xml version="1.0" encoding="utf-8" ?>
<rss version="2.0">
<channel>
<title>Business Logic Toolkit for .NET</title>
<link>http://www.bltoolkit.net</link>
<description />
<lastBuildDate>2009-01-11</lastBuildDate>
<item>
<title>Version 3.1 released</title>
<link>http://www.bltoolkit.net/Download.htm</link>
<description>See <a href="http://www.bltoolkit.net/Download.htm">change log</a></description>
<pubDate>2009-01-11</pubDate>
</item>
<item>
<title>Version 3.0 released</title>
<link>http://www.bltoolkit.net/Download.htm</link>
<description>See <a href="http://www.bltoolkit.net/Download.htm">change log</a></description>
<pubDate>2008-05-21</pubDate>
</item>
<item>
<title>New examples</title>
<link>http://www.bltoolkit.net/Doc/</link>
<description>See the following <a href="http://www.bltoolkit.net/Doc/">link</a></description>
<pubDate>2008-05-10</pubDate>
</item>
</channel>
</rss>
this code get all rss items title
var path = #"D:\rss.xml";
var doc = XDocument.Load(path);
rssTitles = doc.Root.Descendants("item").Elements("title").Select(el => el.Value);
results:
Version 3.1 released
Version 3.0 released
New examples
<Roles>
<BalanceSheets RoleURL="http://fluor.com/role/BalanceSheets" RoleDefination="0020 - CONDENSED CONSOLIDATED BALANCE SHEET">
<Taxonomys>
<StatementOfFinancialPositionAbstract TaxonomyPresentationId="StatementOfFinancialPositionAbstract">
<StatementLineItems TaxonomyPresentationId="StatementOfFinancialPositionAbstract">
<LiabilitiesAndStockholdersEquityAbstract TaxonomyPresentationId="StatementLineItems">
<CommitmentsAndContingencies TaxonomyPresentationId="LiabilitiesAndStockholdersEquityAbstract" />
<OtherLiabilitiesNoncurrent TaxonomyPresentationId="LiabilitiesAndStockholdersEquityAbstract" />
<NonRecourseProjectFinanceDebtNoncurrent TaxonomyPresentationId="LiabilitiesAndStockholdersEquityAbstract" />
<LongTermDebtNoncurrent TaxonomyPresentationId="LiabilitiesAndStockholdersEquityAbstract" />
<LiabilitiesCurrentAbstract TaxonomyPresentationId="LiabilitiesAndStockholdersEquityAbstract">
<BillingsInExcessOfCost TaxonomyPresentationId="LiabilitiesCurrentAbstract" />
<LiabilitiesCurrent TaxonomyPresentationId="LiabilitiesCurrentAbstract" />
<AccountsPayable TaxonomyPresentationId="LiabilitiesCurrentAbstract" />
<BridgeLoan TaxonomyPresentationId="LiabilitiesCurrentAbstract" />
<NonRecourseProjectFinanceDebtCurrent TaxonomyPresentationId="LiabilitiesCurrentAbstract" />
<EmployeeRelatedLiabilities TaxonomyPresentationId="LiabilitiesCurrentAbstract" />
<OtherAccruedLiabilities TaxonomyPresentationId="LiabilitiesCurrentAbstract" />
<ConvertibleDebtCurrent TaxonomyPresentationId="LiabilitiesCurrentAbstract" />
</LiabilitiesCurrentAbstract>
</LiabilitiesAndStockholdersEquityAbstract>
</StatementLineItems>
</StatementOfFinancialPositionAbstract>
</Taxonomys>
</BalanceSheets>
</Roles>

//#attrib vs //name/#attrib in C#

On the XML below, I'm using the SelectSingleNode of XmlDocument to pull out the result value.
evtASxml.SelectSingleNode(#"//#value").Value
returns the value of the first "value."
evtASxml.SelectSingleNode(#"//Result/#value").Value
raises a null exception.
Could someone explain what's going on?
<Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
<System>
<Provider Name="Microsoft-Windows-CAPI2" Guid="{f00f00-f00-f00f00-f00-f00f00f00}" />
<EventID>30</EventID>
<Version>0</Version>
<Level>2</Level>
<Task>30</Task>
<Opcode>0</Opcode>
<Keywords>0x4000000000000001</Keywords>
<TimeCreated SystemTime="2012-04-08T23:43:37.573242200Z" />
<EventRecordID>4828</EventRecordID>
<Correlation ActivityID="{f00f00-f00-f00-f00-f00f00f00f00}" />
<Execution ProcessID="7512" ThreadID="3220" />
<Channel>Microsoft-Windows-CAPI2/Operational</Channel>
<Computer>Matt-Seven</Computer>
<Security UserID="S-f00-f00-f00-f00f00f00-f00f00f00-f00f00f00-f00f00" />
</System>
<UserData>
<CertVerifyCertificateChainPolicy>
<Policy type="CERT_CHAIN_POLICY_SSL" constant="4" />
<Certificate fileRef="f00f00f00f00f00f00f00f00f00f00f00.cer" subjectName="www.example.com" />
<CertificateChain chainRef="{f00f00-f00-f00-f00-f00f00f00f00}" />
<Flags value="0" />
<SSLAdditionalPolicyInfo authType="server" serverName="example.com">
<IgnoreFlags value="0" />
</SSLAdditionalPolicyInfo>
<Status chainIndex="0" elementIndex="0" />
<EventAuxInfo ProcessName="iexplore.exe" />
<CorrelationAuxInfo TaskId="{f00f00-f00-f00-f00-f00f00f00f00}" SeqNumber="4" />
<Result value="800B010F">The certificate's CN name does not match the passed value.</Result>
</CertVerifyCertificateChainPolicy>
</UserData>
</Event>
Numeric values from my event log replaced with f00.
Just guessing, but I think you want //*[#value], and not //#value
The reason for this problem is that the XML document is in a default namespace.
Selecting elements by name when they are in a default namespace is the most FAQ in XPath.
Xpath treats any unprefixed element name as belonging to "no namespace". In your case no Result element exists that is in "no namespace" (all elements are in the "http://schemas.microsoft.com/win/2004/08/events/event" namespace) and thus no node is selected.
In C# it is recommended that you provide an XmlNamespaceManager as the second argument of SelectSingleNode() -- just use the appropriate overload.
Use:
evtASxml.SelectSingleNode(#"//x:Result/#value", yourXmlNamespaceManager).Value
where the association of "x" to the "http://schemas.microsoft.com/win/2004/08/events/event" namespace has been added to yourXmlNamespaceManager using the AddNamespace() method.

Categories