I am pulling information from eBay using their odata feed. I am trying to use linq to pull the specific information we are after. Using linq I can get down to the specific element holding the information we want. What I can't do is figure out how to query the element data to get the specific child elements I want. I could just parse it but really want to learn linq. I am using vb.net as the language. To get the element I am after I use the following:
Sub Main
dim ns = "http://ebayodata.cloudapp.net/"
dim url as string = "http://ebayodata.cloudapp.net/Items?search=1756-L65"
Using reader As XmlReader = XmlReader.Create(url)
While reader.Read()
If reader.NodeType = XmlNodeType.Element AndAlso reader.Name = "entry" Then
GetChildContentElements(reader)
End If
End While
End Using
End Sub
Private Sub GetChildContentElements(reader As XmlReader)
' move to first child
While reader.Read()
If reader.NodeType = XmlNodeType.Element AndAlso reader.Name = "m:properties" Then
Exit While
End If
End While
Dim bookXml As XElement = DirectCast(XNode.ReadFrom(reader), XElement)
Console.WriteLine(bookXml)
End Sub
One of the elements this returns looks like:
<m:properties xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices">
<d:Id>160917851201</d:Id>
<d:UserId>baltisales</d:UserId>
<d:Title>Allen Bradley 1756-L65 /B ControlLogix Processor 32MB Memory *60 DAYS WARRANTY!*</d:Title>
<d:Subtitle m:null="true"></d:Subtitle>
<d:SellingState>Active</d:SellingState>
<d:TimeLeft>P24DT2H25M33S</d:TimeLeft>
<d:Currency>USD</d:Currency>
<d:CurrentPrice m:type="Edm.Double">6446.14</d:CurrentPrice>
<d:MinimumToBid m:type="Edm.Double">6446.14</d:MinimumToBid>
<d:BidCount m:type="Edm.Int32">0</d:BidCount>
<d:Description m:null="true"></d:Description>
<d:QuantitySold m:type="Edm.Int32">0</d:QuantitySold>
<d:AutoPay m:type="Edm.Boolean">false</d:AutoPay>
<d:CharityId m:null="true"></d:CharityId>
<d:Country>US</d:Country>
<d:Compatibility m:null="true"></d:Compatibility>
<d:GalleryUrl>http://thumbs2.ebaystatic.com/m/m3Y01PfuyFhctnJiEet95Gw/140.jpg</d:GalleryUrl>
<d:GlobalId>EBAY-US</d:GlobalId>
<d:PostalCode>21209</d:PostalCode>
<d:ReturnsAccepted m:type="Edm.Boolean">true</d:ReturnsAccepted>
<d:PrimaryCategoryId>97184</d:PrimaryCategoryId>
<d:SecondaryCategoryId m:null="true"></d:SecondaryCategoryId>
<d:ViewItemUrl>http://www.ebay.com/itm/Allen-Bradley-1756-L65-B-ControlLogix-Processor-32MB-Memory-60-DAYS-WARRANTY-/160917851201?pt=BI_Control_Systems_PLCs</d:ViewItemUrl>
<d:PaymentMethods>PayPal ,VisaMC ,AmEx</d:PaymentMethods>
<d:Condition m:type="eBay.Model.Entities.Condition">
<d:Id m:type="Edm.Int32">3000</d:Id>
<d:Name>Used</d:Name>
</d:Condition>
<d:ListingInfo m:type="eBay.Model.Entities.ListingInfo">
<d:BestOfferEnabled m:type="Edm.Boolean">true</d:BestOfferEnabled>
<d:BuyItNowAvailable m:type="Edm.Boolean">false</d:BuyItNowAvailable>
<d:BuyItNowPrice m:type="Edm.Double" m:null="true"></d:BuyItNowPrice>
<d:ConvertedBuyItNowPrice m:type="Edm.Double" m:null="true"> </d:ConvertedBuyItNowPrice>
<d:Gift m:type="Edm.Boolean">false</d:Gift>
<d:ListingType>StoreInventory</d:ListingType>
<d:StartTime m:type="Edm.DateTime">2012-11-06T23:08:18Z</d:StartTime>
<d:EndTime m:type="Edm.DateTime">2013-04-05T23:13:18Z</d:EndTime>
</d:ListingInfo>
<d:Distance m:type="eBay.Model.Entities.Distance" m:null="true"></d:Distance>
<d:ShippingInformation m:type="eBay.Model.Entities.ShippingInformation">
<d:Delimiter m:null="true"></d:Delimiter>
<d:ExpeditedShipping m:type="Edm.Boolean">true</d:ExpeditedShipping>
<d:HandlingTime m:type="Edm.Int32">1</d:HandlingTime>
<d:OneDayShippingAvailable m:type="Edm.Boolean">true</d:OneDayShippingAvailable>
<d:ShippingServiceCost m:type="Edm.Double">0</d:ShippingServiceCost>
<d:ShippingType>FlatDomesticCalculatedInternational</d:ShippingType>
</d:ShippingInformation>
</m:properties>
I am struggling with querying the above to get the specific child elements we need to work with. The ":" in the tags seems to be confusing using namespaces. What I would like to do is to be able to query the element to get values for d:Id, d:UserId, d:Currentprice, etc. Any suggestions would be welcomed.
Try using WCF data services client. It can generate proxy classes for you that would simplify things. Refer to the documentation here.
Sample code for doing custom url's with generated WCF DS client,
const string baseAddress = "http://ebayodata.cloudapp.net/";
EBayData ebay = new EBayData(new Uri(baseAddress));
var items = ebay.Execute<Item>(new Uri(baseAddress + "Items?search=1756-L65"));
foreach (var item in items)
{
Console.WriteLine(item.Title);
}
Related
I'm using EF Core 2.1 and i have a Model SettingInformation. The SettingInformation has a Property Setting As ICollection(Of Setting).
The Setting Property has several Properties like Client As Client, User as User and also Workspace As Workspace. It's a bit complicated. Please see the Attached Diagram-Image.
Model-Diagram(Part of it)
Now i have the problem, that i'd like to get the complete Information of a Settinginformation.
The following code i have to get all Informations of a SettingInformation
Public Async Function GetCompleteSettingInformations(settingInfoId As Integer) As Task(Of SettingInformation)
Dim q As IQueryable(Of SettingInformation) = GetSettingInfoDefaultQuery()
q = q.Where(Function(s) s.SettingInformationId = settingInfoId)
q = q.Include(Function(i) i.Settings).ThenInclude(Function(i) i.User) _
.Include(Function(i) i.Settings).ThenInclude(Function(i) i.Workspace) _
.Include(Function(i) i.Settings).ThenInclude(Function(i) i.Client) _
.Include(Function(i) i.Protocol)
Dim ret = Await q.SingleOrDefaultAsync
Return ret
End Function
OK, this code works, but now i'd like to refactor this, because for example, I do not need the UserImage or the 'FailedLogins' of User when the 'LinkedToUser' Property of 'Protocol' is not nothing.
What i needed:
The complete 'SettingInformation' - OK easy
The 'Settings' From 'SettingInformation' (ICollection) - OK i can get this with the Include but in 'Settings':
only the 'UserName', 'FirstName' and 'LastName' from 'User' if 'User' is not Nothing
only the 'ClientShortName' and 'ClientLongName' of 'LinkedToClient' if 'Client is not Nothing
only the 'WorkspaceName' and 'WorkspaceLocation' of 'Workspace' id the 'Workspace' is not Nothing.
I hope so here is anybody who can help me to optimize this Query because now i also cat for example the UserImage for each Setting and this results in a long loadingtime.
EDIT:
OK, now i have tried to do that with EagerLoading. But the Select is ignored. But why? the following code:
'Alle WorkspaceIDs ermitteln für welche es Settingmodifikationen gibt
Dim wsIds As List(Of Integer) = ret.Settings.Where(Function(u) u.WorkspaceId.HasValue).Select(Function(u) u.WorkspaceId.Value).ToList
Await ContextInternal.Workspaces.Where(Function(u) wsIds.Contains(u.WorkspaceId)) _
.Select(Function(su) New Workspace() With {.WorkspaceName = su.WorkspaceName, .WorkspaceLocation = su.WorkspaceLocation, .WorkspaceDesciption = su.WorkspaceDesciption, .WorkspaceId = su.WorkspaceId, .Settings = su.Settings}).AsTracking.LoadAsync
Loads all workspaces that are related in Protocols. I will only get the columns ID, Description, Location and Name. But i get ALL Columns?
The following SQL is generated:
SELECT [u].[WorkspaceId],
[u].[CreatedBy],
[u].[CreatedOn],
[u].[CreationTimestamp],
[u].[DeletedFlag],
[u].[DeletedTimestamp],
[u].[LastUpdateBy],
[u].[LastUpdateOn],
[u].[LastUpdateTimestamp],
[u].[WorkspaceDesciption],
[u].[WorkspaceLastOnline],
[u].[WorkspaceLocation],
[u].[WorkspaceLocked],
[u].[WorkspaceName]
FROM [Workspaces] AS [u]
WHERE [u].[WorkspaceId] IN (1)
ORDER BY [u].[WorkspaceId]
I have a dnn 7.2.2 development site running under dnndev.me on my local machine. I have created a simple product catalogue module and am trying to integrate the new search for dnn 7.
Here is the implementation of ModuleSearchBase in my feature/business controller
Imports DotNetNuke.Entities.Modules
Imports DotNetNuke.Services.Exceptions
Imports DotNetNuke.Services.Search
Imports DotNetNuke.Common.Globals
Namespace Components
Public Class FeatureController
Inherits ModuleSearchBase
Implements IUpgradeable
Public Overrides Function GetModifiedSearchDocuments(moduleInfo As ModuleInfo, beginDate As Date) As IList(Of Entities.SearchDocument)
Try
Dim SearchDocuments As New List(Of Entities.SearchDocument)
'get list of changed products
Dim vc As New ViewsController
Dim pList As List(Of vw_ProductList_Short_Active) = vc.GetProduct_Short_Active(moduleInfo.PortalID)
If pList IsNot Nothing Then
''for each product, create a searchdocument
For Each p As vw_ProductList_Short_Active In pList
Dim SearchDoc As New Entities.SearchDocument
Dim ModID As Integer = 0
If p.ModuleId Is Nothing OrElse p.ModuleId = 0 Then
ModID = moduleInfo.ModuleID
Else
ModID = p.ModuleId
End If
Dim array() As String = {"mid=" + ModID.ToString, "id=" + p.ProductId.ToString, "item=" + Replace(p.Name, " ", "-")}
Dim DetailUrl = NavigateURL(moduleInfo.TabID, GetPortalSettings(), "Detail", array)
With SearchDoc
.AuthorUserId = p.CreatedByUserId
.Body = p.ShortInfo
.Description = p.LongInfo
.IsActive = True
.PortalId = moduleInfo.PortalID
.ModifiedTimeUtc = p.LastUpdatedDate
.Title = p.Name + " - " + p.ProductNumber
.UniqueKey = Guid.NewGuid().ToString()
.Url = DetailUrl
.SearchTypeId = 2
.ModuleId = p.ModuleId
End With
SearchDocuments.Add(SearchDoc)
Next
Return SearchDocuments
Else
Return Nothing
End If
Catch ex As Exception
LogException(ex)
Return Nothing
End Try
End Function
End Class
End Namespace
I cleared the site cache and then I manually started a search re-index. I can see from the host schedule history that the re-index is run and completes.
PROBLEM
None of the items in the above code are added to the index. I even used the Luke Inspector to look into the lucene index and that confirms that these items are not added.
QUESTION
I need help figuring out why these items are not getting added or I need help on how to debug the indexing to see if anything is going run during that process.
Thanks in Advance
JK
EDIT #1
I ran the following procedure in Sql Server to see if the module is even listed in the search modules:
exec GetSearchModules[PortalId]
The module in question does appear in this list. The indexing is called for the featureController, but the results are not added to the lucene index. Still need help.
EDIT #2
So I upgraded to 7.3.1 in the hopes that something during the installation would fix this issue. But it did not. The search documents are still getting created/ returned by the GetModifiedSearchDocuments function but the documents are not being added to the Lucene index and therefore do not appear in the search results.
EDIT #3
The break point is not getting hit like i thought after the upgrade, but I added a try catch to log exceptions and the following error log is getting created when I try to manually re-index (cleaned up to keep it short)
AssemblyVersion:7.3.1
PortalID:-1
PortalName:
DefaultDataProvider:DotNetNuke.Data.SqlDataProvider, DotNetNuke
ExceptionGUID:d0a443da-3d68-4b82-afb3-8c9183cf8424
InnerException:Sequence contains more than one matching element
Method:System.Linq.Enumerable.Single
StackTrace:
Message:
System.InvalidOperationException: Sequence contains more than one matching element
at System.Linq.Enumerable.Single[TSource](IEnumerable`1 source, Func`2 predicate)
at DotNetNuke.Services.Scheduling.Scheduler.CoreScheduler.LoadQueueFromTimer()
at DotNetNuke.Services.Scheduling.Scheduler.CoreScheduler.Start()
Source:
Server Name: KING-PC
EDIT #4
Okay, I fixed the problem in edit three following This Disucssion on the DNN issue tracker, but still no items being added to the lucene index.
The breakpoint is hit, and once i leave the debugger running for a while i get the following error:
{"Exception of type 'Lucene.Net.Index.MergePolicy+MergeException' was
thrown."} {"Cannot overwrite:
C:\websites\dnndev.me\App_Data\Search\_1f0.fdt"}
Looks like a permission error. I'll see what I can work out
J King,
I just finished a series on DNNHero.com on Implementing Search in your Module. Parts 3 and 4 are implementing and debugging your ModuleSearchBase implementation.
EDIT: Remove your assignment to the SearchTypeId in your implementation
Also, here is a sample snippet to see how i am setting the attributes of the SearchDocument. Again, watch my video for a whole bunch of other potential pitfalls in the Search implementation.
SearchDocument doc = new SearchDocument
{
UniqueKey = String.Format("{0}_{1}_{2}",
moduleInfo.ModuleDefinition.DefinitionName, moduleInfo.PortalID, item.ItemId),
AuthorUserId = item.AssignedUserId,
ModifiedTimeUtc = item.LastModifiedOnDate.ToUniversalTime(),
Title = item.ItemName,
Body = item.ItemDescription,
Url = "",
CultureCode = "en-US",
Description = "DotNetNuclear Search Content Item",
IsActive = true,
ModuleDefId = moduleInfo.ModuleDefID,
ModuleId = item.ModuleId,
PortalId = moduleInfo.PortalID,
TabId = tab
};
I've been looking for this on the web for 4 days, and i still have no clue why my code isn't working...
I'm using an ASP.NET MVC 4 application with a service reference to a sharepoint listData in order to CRUD datas.
Here is how i retrieve my DataContext :
var datacontext = new CogniTICDataContext(new Uri("http://my.service.url/_vti_bin/listdata.svc"));
datacontext.IgnoreResourceNotFoundException = true;
datacontext.Credentials = new NetworkCredential("user", "pass", "Domain");
datacontext.MergeOption = MergeOption.OverwriteChanges;
return datacontext;
It's perfectly working with single and multi lookup fields. But with multi choice fields, nothing is working.
Here is what i'm trying :
foreach (string domComp in jsonDomComp.Split(';'))
{
PrestatairesFormationsDomaineDeCompétencesValue domaineDeCompetence =
PrestatairesFormationsDomaineDeCompétencesValue
.CreatePrestatairesFormationsDomaineDeCompétencesValue(domComp);
prestataire.DomaineDeCompétences.Add(domaineDeCompetence);
//dc.AttachTo("DomainesDeCompétence", domaineDeCompetence);
//dc.AddLink(prestataire, "DomComp", domaineDeCompetence);
}
//SaveChanges in batch mode
dc.UpdateObject(prestataire);
dc.SaveChanges(System.Data.Services.Client.SaveChangesOptions.Batch);
I commented the AttachTo and AddLink because my "DomaineDeCompétences" are not entities ! It's not a multi lookup field and i have no power to change that. Though, if I try to add those two lines, I have a ResourceNotFoundException because the entity has no id, and that's because it's not an entity ! (I already tried : dc.IgnoreResourceNotFoundException = true;)
I have no errors, it just doesn't work... Can anyone help me ?
Best regards,
Flavio
instead of using
prestataire.DomaineDeCompétences = ...
just use
prestataire.DomaineDeCompétencesValue = domComp
there you can assign the string directly.
Please have a look a similar question on SO
SP 2013 - Updating a multi-value lookup field via the REST API
and
Updating Lookup Values with the REST API
Also possible:
MyListService.Credentials = CredentialCache.DefaultCredentials;
MyListService.Url = "http://yourserver/_vti_bin/lists.asmx";
XmlDocument updateRequest = new XmlDocument();
String updateBatch = "<Batch OnError='Continue'>" +
"<Method ID='1' Cmd='Update'>" +
"<Field Name='ID'>2</Field>" +
"<Field Name='Location'>1;#;#2</Field>" +
"<Field Name='Owners'>1;#;#7</Field>" +
"<Field Name='Choices'>Value1;#Value2</Field>" +
"</Method>" +
"</Batch>";
updateRequest.LoadXml(updateBatch);
XmlNode deleteResult = MyListService.UpdateListItems("Tasks", updateRequest.DocumentElement);
I am trying to parse an TCX document similiar to the one used in this post: Import TCX into R using XML package
Only I'm trying to use XmlDocument.SelectNodes and SelectSingleNode instead of getNodeSet. The line with xmlns looks like this:
<TrainingCenterDatabase xmlns="http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2 http://www.garmin.com/xmlschemas/TrainingCenterDatabasev2.xsd">
If I remove the xmlns and just have , I can parse it without any problems.
My (vb.net) code:
Dim tcxXmlDocument As New System.Xml.XmlDocument()
tcxXmlDocument.Load(tcxFile)
Dim xmlnsManager = New System.Xml.XmlNamespaceManager(tcxXmlDocument.NameTable)
Dim trackpoints As New List(Of Trackpoint)
For Each tpXml As System.Xml.XmlNode In tcxXmlDocument.SelectNodes("//Trackpoint", xmlnsManager)
Dim newTrackpoint As New Trackpoint
With newTrackpoint
.Time = tpXml.SelectSingleNode("Time").InnerText
.LatitudeDegrees = tpXml.SelectSingleNode("Position/LatitudeDegrees").InnerText
.LongitudeDegrees = tpXml.SelectSingleNode("Position/LongitudeDegrees").InnerText
.HeartRateBpm = tpXml.SelectSingleNode("HeartRateBpm").InnerText
End With
trackpoints.Add(newTrackpoint)
Next
How can I configure the XmlNamespaceManager so that I can access the nodes in such a tcx document?
Thanks,
Jason
Use the XmlNamespaceManager.AddNamespace() method to associate a preffix (say "x") with the namespace "http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2".
Then in your XPath expression, pefix every element name with the "x" prefix.
Replace this:
//Trackpoint
with:
//x:Trackpoint
Replace this:
Time
with:
x:Time
Replace this:
Position/LatitudeDegrees
with:
x:Position/x:LatitudeDegrees
Replace this:
Position/LongitudeDegrees
with:
x:Position/x:LongitudeDegrees
Finally, replace this:
HeartRateBpm
with:
x:HeartRateBpm
I've been using XML serialization for a while, and today I realized something really odd. If I have a new line right after a "dot" (.), when i deserialize, I lose the dot. Has anyone ever had this happen to them? The following is my serialization code:
Serialize
Dim xmlSerializer As New System.Xml.Serialization.XmlSerializer(GetType(SilverWare.Licensing.Common.StoreLicense), New System.Type() {GetType(SilverWare.Licensing.Common.StationLicense)})
Dim gen As LicenseGenerator
If store Is Nothing Then
Throw New ArgumentNullException("store")
ElseIf store.StationLicenses Is Nothing Then
Throw New ArgumentNullException("store.StationLicenses")
ElseIf store.StationLicenses.Length = 0 Then
Throw New ArgumentOutOfRangeException("store.StationLicenses", "Must contain at least one element.")
End If
' Create a license generator for issuing new license keys.
gen = New LicenseGenerator(store)
' Generate store key.
store.LicenseKey = gen.GenerateLicenseKey
' Generate individual station keys.
For Each station In store.StationLicenses
station.LicenseKey = gen.GenerateLicenseKey(station)
Next
' Write license to file.
Using xFile As Xml.XmlWriter = Xml.XmlWriter.Create(licenseFile)
xmlSerializer.Serialize(xFile, store)
xFile.Close()
End Using
Deserialize
Dim xmlDeserializer As New System.Xml.Serialization.XmlSerializer(GetType(SilverWare.Licensing.Common.StoreLicense), New System.Type() {GetType(SilverWare.Licensing.Common.StationLicense)})
Dim result As SilverWare.Licensing.Common.StoreLicense
Using xFile As Xml.XmlReader = Xml.XmlReader.Create(licenseFile)
result = DirectCast(xmlDeserializer.Deserialize(xFile), SilverWare.Licensing.Common.StoreLicense)
xFile.Close()
End Using
Return result
The really funny part is that if I have a space after the dot, or remove the new line character, there are no problems. This only happens if it is dot which I find mind boggling.
Here is a quick sample of my XML file that was created when I serialized:
<?xml version="1.0" encoding="utf-8" ?>
<StoreLicense xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
...
<ReceiptAddress>98 N. Washington St.
Berkeley Springs West Virginia</ReceiptAddress>
<Name>Ambrae House at Berkeley Springs</Name>
<AliasName>Ambrae House</AliasName>
<Address1>98 N. Washington St.</Address1>
<Address2 />
...
</StoreLicense>
The line that is having the problem is the ReceiptAddress Node.
This post on MSDN seems to answer your question.
MSDN: Serialize String containing only whitespace such as a " " character
From that post, try this:
<XmlAttribute("xml:space")> _
Public SpacePreserve As [String] = "preserve"
This creates a root node like the following:
<DataImportBase xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xml:space="preserve">
Jim
Since I was using someone elses dll, I didn't even think that it would be modifying my data when we imported it. What was happening was that the other programmer had a reg_ex that was looking for a dot before a new line. That was my issue, and my grief for 3 months.