I have a xml file and I want to search in it with an autocomplete box.
I use code below but the it crashed. How can I fix it or is there a way better?
XDocument loadedData = XDocument.Load("BankCode.xml");
var data = from query in loadedData.Descendants("BankCode")
select new BankData
{
BankName= (string)query.Element("Bank"),
};
this.acBox.ItemsSource = data;
XDocument loadedCustomData = XDocument.Load("BankCode.xml");
var filteredData = from c in loadedCustomData.Descendants("Bank")
where c.Attribute("Code").Value == acBox.Text
select new BankData()
{
Code= c.Attribute("Code").Value
};
listBox1.ItemsSource = filteredData;
I want to create an app that when the user type the bank name in autocomplete box after pressing the search button the bank code has shown to him/her. (!!The acBox is an autocomplete box.)
It seems 1 of your Bank nodes does not have a Code attribute.
You should add a NULL check:
var filteredData = from c in loadedCustomData.Descendants("Bank")
where c.Attribute("Code") != null && c.Attribute("Code").Value == acBox.Text
select new BankData()
{
Code= c.Attribute("Code").Value
};
Related
I've been banging my head on the desktop for the past couple of hours trying to decipher this issue.
I'm trying to query an XML file with Linq, the xml has the following format:
<MRLGroups>
<MRLGroup>
<MarketID>6084</MarketID>
<MarketName>European Union</MarketName>
<ActiveIngredientID>28307</ActiveIngredientID>
<ActiveIngredientName>2,4-DB</ActiveIngredientName>
<IndexCommodityID>59916</IndexCommodityID>
<IndexCommodityName>Cucumber</IndexCommodityName>
<ScientificName>Cucumis sativus</ScientificName>
<MRLs>
<MRL>
<PublishedCommodityID>60625</PublishedCommodityID>
<PublishedCommodityName>Cucumbers</PublishedCommodityName>
<MRLTypeID>238</MRLTypeID>
<MRLTypeName>General</MRLTypeName>
<DeferredToMarketID>6084</DeferredToMarketID>
<DeferredToMarketName>European Union</DeferredToMarketName>
<UndefinedCommodityLinkInd>false</UndefinedCommodityLinkInd>
<MRLValueInPPM>0.0100</MRLValueInPPM>
<ResidueDefinition>2,4-DB</ResidueDefinition>
<AdditionalRegulationNotes>Comments.</AdditionalRegulationNotes>
<ExpiryDate xsi:nil="true" />
<PrimaryInd>true</PrimaryInd>
<ExemptInd>false</ExemptInd>
</MRL>
<MRL>
<PublishedCommodityID>60626</PublishedCommodityID>
<PublishedCommodityName>Gherkins</PublishedCommodityName>
<MRLTypeID>238</MRLTypeID>
<MRLTypeName>General</MRLTypeName>
<DeferredToMarketID>6084</DeferredToMarketID>
<DeferredToMarketName>European Union</DeferredToMarketName>
<UndefinedCommodityLinkInd>false</UndefinedCommodityLinkInd>
<MRLValueInPPM>0.0100</MRLValueInPPM>
<ResidueDefinition>2,4-DB</ResidueDefinition>
<AdditionalRegulationNotes>More Comments.</AdditionalRegulationNotes>
<ExpiryDate xsi:nil="true" />
<PrimaryInd>false</PrimaryInd>
<ExemptInd>false</ExemptInd>
</MRL>
</MRLs>
</MRLGroup>
So far i've created classes for the "MRLGroup" section of the file
var queryMarket = from market in doc.Descendants("MRLGroup")
select new xMarketID
{
MarketID = Convert.ToString(market.Element("MarketID").Value),
MarketName = Convert.ToString(market.Element("MarketName").Value)
};
List<xMarketID> markets = queryMarket.Distinct().ToList();
var queryIngredient = from ingredient in doc.Descendants("MRLGroup")
select new xActiveIngredients
{
ActiveIngredientID = Convert.ToString(ingredient.Element("ActiveIngredientID").Value),
ActiveIngredientName = Convert.ToString(ingredient.Element("ActiveIngredientName").Value)
};
List<xActiveIngredients> ingredientes = queryIngredient.Distinct().ToList();
var queryCommodities = from commodity in doc.Descendants("MRLGroup")
select new xCommodities {
IndexCommodityID = Convert.ToString(commodity.Element("IndexCommodityID").Value),
IndexCommodityName = Convert.ToString(commodity.Element("IndexCommodityName").Value),
ScientificName = Convert.ToString(commodity.Element("ScientificName").Value)
};
List<xCommodities> commodities = queryCommodities.Distinct().ToList();
After i got the "catalogues" I'm trying to query the document against the catalogues to achieve some sort of "groups", after all this, i'm going to send this data to the database, the issue here is that the xml files are around 600MB each and i get the everyday, so my approach is to create catalogues and just send the MRLs to the database joined to the "header" table that contains the Catalogues IDs, here's what i've done so far but failed miserably:
//markets
foreach (xMarketID market in markets) {
//ingredients
foreach (xActiveIngredients ingredient in ingredientes) {
//commodities
foreach (xCommodities commodity in commodities) {
var mrls = from m in doc.Descendants("MRLGroup")
where Convert.ToString(m.Element("MarketID").Value) == market.MarketID
&& Convert.ToString(m.Element("ActiveIngredientID").Value) == ingredient.ActiveIngredientID
&& Convert.ToString(m.Element("IndexCommodityID").Value) == commodity.IndexCommodityID
select new
{
ms = new List<xMRLIndividial>(from a in m.Element("MRLs").Descendants()
select new xMRLIndividial{
publishedCommodityID = string.IsNullOrEmpty(a.Element("PublishedCommodityID").Value) ? "" : a.Element("PublishedCommodityID").Value,
publishedCommodityName = a.Element("PublishedCommodityName").Value,
mrlTypeId = a.Element("MRLTypeID").Value,
mrlTypeName = a.Element("MRLTypeName").Value,
deferredToMarketId = a.Element("DeferredToMarketID").Value,
deferredToMarketName = a.Element("DeferredToMarketName").Value,
undefinedCommodityLinkId = a.Element("UndefinedCommodityLinkInd").Value,
mrlValueInPPM = a.Element("MRLValueInPPM").Value,
residueDefinition = a.Element("ResidueDefinition").Value,
additionalRegulationNotes = a.Element("AdditionalRegulationNotes").Value,
expiryDate = a.Element("ExpiryDate").Value,
primaryInd = a.Element("PrimaryInd").Value,
exemptInd = a.Element("ExemptInd").Value
})
};
foreach (var item in mrls)
{
Console.WriteLine(item.ToString());
}
}
}
}
If you notice i'm trying to get just the MRLs descendants but i got this error:
All i can reach on the "a" variable is the very first node of MRLs->MRL not all of them, what is going on?
If you guys could lend me a hand would be super!
Thanks in advance.
With this line...
from a in m.Element("MRLs").Descendants()
...will iterate through all sub-elements, including children of children. Hence your error, since your <PublishedCommodityID> element does not have a child element.
Unless you want to specifically return all child elements of all levels, always use the Element and Elements axis instead of Descendant and Descendants:
from a in m.Element("MRLs").Elements()
That should solve your problem.
However, your query is also difficult to read with the nested foreach loops and the multiple tests for the IDs. You can simplify it with a combination of LINQ and XPath:
var mrls =
from market in markets
from ingredient in ingredientes
from commodity in commodities
let xpath = $"/MRLGroups/MRLGroup[{market.MarketId}]" +
$"[ActiveIngredientID={ingredient.ActiveIngredientId}]" +
$"[IndexCommodityID={commodity.IndexCommodityID}]/MRLs/MRL"
select new {
ms =
(from a in doc.XPathSelectElements(xpath)
select new xMRLIndividial {
publishedCommodityID = string.IsNullOrEmpty(a.Element("PublishedCommodityID").Value) ? "" : a.Element("PublishedCommodityID").Value,
publishedCommodityName = a.Element("PublishedCommodityName").Value,
mrlTypeId = a.Element("MRLTypeID").Value,
mrlTypeName = a.Element("MRLTypeName").Value,
deferredToMarketId = a.Element("DeferredToMarketID").Value,
deferredToMarketName = a.Element("DeferredToMarketName").Value,
undefinedCommodityLinkId = a.Element("UndefinedCommodityLinkInd").Value,
mrlValueInPPM = a.Element("MRLValueInPPM").Value,
residueDefinition = a.Element("ResidueDefinition").Value,
additionalRegulationNotes = a.Element("AdditionalRegulationNotes").Value,
expiryDate = a.Element("ExpiryDate").Value,
primaryInd = a.Element("PrimaryInd").Value,
exemptInd = a.Element("ExemptInd").Value
}).ToList()
};
i have two list list content listearticle and this the code of this list:
model = (
from article in db.Article
select new
{
ID = article.ID,
ARTICLE = article.CODEARTICLE,
PRIX= article.PRIX,
STOCK=article.STOCK,
IMAGE = article.Image,
DESCRIPTION= article.REFERENCE,
});
and another content list convention and this is the code :
var query = (
from article in db.convention
select new
{
ID = article.ID,
ARTICLE = article.CODEARTICLE,
PRIX = article.Prix,
});
i want to have a list listarticleconvention like this:
foreach (dynamic aa in model)
{
foreach (dynamic aa1 in list1)
{
if (aa.ARTICLE == aa1.ARTICLE)
{
aa.PRIXVHT = aa1.PRIXVHT;
}
}
}
Can someone help me to edit PRIXVHT when this article exist in list1 and thank you for your help
the error apperead is Additional information: Property or indexer '<>f__AnonymousType3.PRIXVHT' cannot be assigned to -- it is read only
i know that's just read read only but i need to edit it how can i do it
N.B/i have to use a form like that i mean something like foreach in this two list
You can join db.Article to db.convention and then select article.PRIX if query.PRIX is null.
from articleA in db.Article
join articleC in db.convention on articleC.ID equals articleA.ID into temp
from query in temp.DefaultIfEmpty()
select new
{
ID = articleA.ID,
ARTICLE = articleA.CODEARTICLE,
PRIX = (query== null ? articleA.PRIX : query.PRIX),
STOCK = articleA.STOCK,
IMAGE = articleA.Image,
DESCRIPTION = articleA.REFERENCE,
});
Please note that I'm new to C# and I learn it right now :) I couldn't find something similar to my problem, so I came here.
I have an application in which I add customers (it's in the final stage). All customers are stored in an XML file. Every single customer gets a new customer number. In my xml file I got an XmlNode called CustNo. Now if the user add a new customer and type in a number which already exist, it should pop up a message box to say that this number already exists. I got this c# code:
XDocument xdoc = XDocument.Load(path + "\\save.xml");
var xmlNodeExist = String.Format("Buchhaltung/Customers/CustNo");
var CustNoExist = xdoc.XPathSelectElement(xmlNodeExist);
if (CustNoExist != null)
{
MessageBox.Show("asdf");
}
And my XML file looks like this:
<Buchhaltung>
<Customers>
<CustNo>12</CustNo>
<Surname>Random</Surname>
<Forename>Name</Forename>
<Addr>Address</Addr>
<Zip>12345</Zip>
<Place>New York</Place>
<Phone>1234567890</Phone>
<Mail>example#test.com</Mail>
</Customers>
<Customers>
<CustNo>13</CustNo>
<Surname>Other</Surname>
<Forename>Forename</Forename>
<Addr>My Address</Addr>
<Zip>67890</Zip>
<Place>Manhattan</Place>
<Phone>0987654321</Phone>
<Mail>test#example.com</Mail>
</Customers>
</Buchhaltung>
But then the message box always pops up. What am I doing wrong?
That's because your XPath return all CustNo elements, no matter of it's content.
Try following:
var myNumber = 12;
var xmlNodeExist = String.Format("Buchhaltung/Customers/CustNo[. = {0}]", myNumber.ToString());
or using First and LINQ to XML:
var myNumber = 12;
var xmlNodeExist = "Buchhaltung/Customers/CustNo";
var CustNoExist = xdoc.XPathSelectElements(xmlNodeExist).FirstOrDefault(x => (int)x == myNumber);
You are currently testing for existance of any 'CustNo' element. See this reference about the XPath syntax.
Your XPath should say something like this:
Buchhaltung//Customers[CustNo='12']
which would say "any customers element containing a 'CustNo' element with value = '12'"
Combining that with your current code:
var custNoGivenByCustomer = "12";
var xmlNodeExistsXpath = String.Format("Buchhaltung//Customers[CustNo='{0}']", custNoGivenByCustomer );
var CustNoExist = xdoc.XPathSelectElement(xmlNodeExistsXpath);
You can use LINQ to XML
var number = textBox1.Text;
var CustNoExist = xdoc.Descendants("CustNo").Any(x => (string)x == number);
if(CustNoExist)
{
MessageBox.Show("asdf");
}
This is because you select the CustNo elements regardless of their value. This will filter it to the desired customer number:
int custNo = 12;
var xmlNodeExist = String.Format("Buchhaltung/Customers[CustNo={0}]", custNo);
It selects the Customers elements instead, but since you're just checking for existence, that's unimportant.
W3Schools has a good tutorial/reference on XPath.
In an ASP.NET application I have a IreeView.
Here is one of the nodes in the view:
<td style="white-space: nowrap;">
<input id="TreeView1n10CheckBox" type="checkbox" checked="checked" name="TreeView1n10CheckBox">
<a id="TreeView1t10" onclick="TreeView_SelectNode(TreeView1_Data, this,'TreeView1t10');" href="javascript:__doPostBack('TreeView1','sPreAnalytical\\Test Requisitions\\2 Specimens: 1 Req')" class="TreeView1_0">2 Specimens: 1 Req</a>
As you can see it is a checkbox and there is text after it 'TreeView1','sPreAnalytical\\Test Requisitions\\2 Specimens: 1 Req'
How do I get the text 2 Specimens: 1 Req' on the client side, and how do I modify this text using JavaScript and display the modified TreeView to the client?
this works beautifully:
function check_OnTreeNodeChecked(event) {
var TreeNode = event.srcElement || event.target;
if (TreeNode.tagName == "INPUT" && TreeNode.type == "checkbox") {
if (TreeNode.checked) {
var elNode = document.getElementById("TreeView1t10");
var sText = elNode.innerText || elNode.innerHTML;
alert(sText);
elNode.innerHTML = "Whatever you want";
}
}
}
however since i need to modify the specific text next to the checkbox i need to be able to know which element id it was instead of implicitly specifying var elNode = document.getElementById("TreeView1t10");
Question how do i get the element id of the box that was checked?
The text can be retrieved using:
var elNode = document.getElementById("TreeView1t10");
var sText = elNode.innerText || elNode.innerHTML;
Modify it using:
elNode.innerHTML = "Whatever you want";
To get the ID of the tree node in your click handler:
From the top of my head, untested, something like this will get you the tree node from the checkbox ID:
Checkbox ID = "TreeView1n10CheckBox"; replace "CheckBox" with nothing, so we have
"TreeView1n10". Then replace the "n" with "t" and we have "TreeView1t10", which is
the ID of the corresponding anchor tag.
var sTreeID = TreeNode.id.replace("CheckBox", "").replace("n", "t");
var elTreeNode = document.getElementById(sTreeID);
With jQuery, it's quite simple...
var oldText = $('.TreeView1_0').text();
$('.TreeView1_0').text('new text here');
EDIT :
example here : http://jsfiddle.net/shaneblake/ZG888/
With a tree view the class is probably utilized multiple times so accessing the specific element would be of more use.
var oldText = $('#TreeView1t10').html();
If you need to update all the trees text you can loop through them pretty simply as well.
$('.TreeView1t10').each(function() {
var oldText = $(this).find('a').html();
});
i need to store all the informationen from the xml in an array. My code doesn't work, because I always get just the first item from the xml.
Does anyone know how to fix this?
XDocument xdoc = XDocument.Load("http://www.thefaxx.de/xml/nano.xml");
var items = from item in xdoc.Descendants("items")
select new
{
Title = item.Element("item").Element("title").Value,
Description = item.Element("item").Element("description").Value
};
foreach (var item in items)
{
listView1.Items.Add(item.Title);
}
How about:
var items = from item in xdoc.Descendants("item")
select new
{
Title = item.Element("title").Value,
// *** NOTE: xml has "desc", not "description"
Description = item.Element("desc").Value
};
It is a little hard to be sure without sample xml - but it looks like you intend to loop over all the <item>...</item> elements - which is what the above does. Your original code loops over the (single?) <items>...</items> element(s), then fetches the first <item>...</item> from within it.
edit after looking at the xml; this would be more efficient:
var items = from item in xdoc.Root.Elements("item")
select new {
Title = item.Element("title").Value,
Description = item.Element("desc").Value
};