How to populate XML object with data, based on XSD - c#

I need to export data into XML file, using XSD. There are many examples how to do it, but most of them do not show how to popuate the actual data, but to save the object as an XML. The one I could find didn't work for me.
1) I use an xsd file of Agresso http://services.agresso.com/schema/ABWInvoice/2011/11/14/ABWInvoice.html
which I have successfully downloaded and generated a class with xsd.exe command.
2) I have added this class to my project. ABWInvoice is the class for the complexType element Invoice. The xml may contain more than one invoice, hence its maxOccurs is set to "unbounded". Each Invoice can have InvoiceNo element and Header complex element.
3) I have started to write the code and first thought I can use a list, as the number of invoices is dynamic. But List<ABWInvoice> list = new ABWInvoice(); didn't work "Cannot implicitly convert type 'abc.Agresso.ABWInvoice' to 'System.Collections.Generic.List'", so I have decided to at least try to have one record and go from there, but oAgresso.Invoice[0].Header fails in runtime with System.NullReferenceException: 'Object reference not set to an instance of an object.'
private void CreateXMLHeader()
{
var oAgresso = new ABWInvoice { };
oAgresso.Invoice[0] = new ABWInvoiceInvoice
{ InvoiceNo = "1" };
oAgresso.Invoice[0].Header = new ABWInvoiceInvoiceHeader()
{
OrderRef = "5678",
InvoiceDate = Date.Now
};
//var agressoXMLImport = Shared.XMLHelper.ReadXml<ABWInvoice>(#"E:\temp\ABW_Invoice_Test.xml");
Shared.XMLHelper.SaveXml<ABWInvoice>(oAgresso, #"e:\temp\ABW_Export_Test.xml");
}
Can you advise on how
1) build a dynamic array (I do not know the amount of invoices, when I start building the XML;
2)What is wrong with my current code?
Much appreciated!

Member arrays need to be initialized with known size, so its easier to make a List of ABWInvoiceInvoice then populate it with your data by using add method and at the end assign whole list to your member array
private void CreateXMLHeader()
{
var oAgresso = new ABWInvoice { };
List<ABWInvoiceInvoice> invlist = new List<ABWInvoiceInvoice>();
invlist.Add(new ABWInvoiceInvoice { InvoiceNo = "1" ,
Header= new ABWInvoiceInvoiceHeader()
{
OrderRef = "5678",
InvoiceDate = DateTime.Now
}
});
oAgresso.Invoice = invlist.ToArray();

Related

How to output or format data as a table in LinqPad?

I was wandering how to output (or format) data in LinqPad as a table. I know that for some data types LinqPad generates tables. For example, it can dump 2D-arrays:
After googling, I didn't find a direct answer. Let's say I want to create a two-columns table for DateOnly.ToString(...):
format string
formatted value
toString()
27/12/2022
ToString(DD.MM.YYYY)
DD.12.YYYY
ToString(dd.MM.yyyy)
27.12.2022
How can I build such a table in LinqPad?
It seems like the correct solution is to use a collection of anonymous types to build tables.
The following code:
DateOnly dateOnlyNow = DateOnly.FromDateTime(DateTime.Now);
var output = new[] {
new { method = "ToString()", value = dateOnlyNow.ToString() },
new { method = "ToString(DD.MM.YYYY)", value = dateOnlyNow.ToString("DD.MM.YYYY") },
new { method = "ToString(dd.MM.yyyy)", value = dateOnlyNow.ToString("dd.MM.yyyy") },
};
output.Dump();
produces the expected result:

Is there a way to index through objects dnyamically in Scriban with C#?

Working on a PDF generator and it uses the Templating Engine Scriban and LaTeX. Although I cannot seem to reference the C# object Scriban is trying to read via index notation (use the data at this index of the array). I mean something like this:
{~for index in 0..document.template_data.tables.size~}}
{{ document.template_data.tables[index].data_matrix }}
{{ end }}
I get: Object document.template_data.tables[index] is null which ultimately means for whatever reason the compiler cannot retrieve that object.
Q: Is the data actually in the objects?
A: Yes, I hardcoded in numbers like 0 and 1 and got relevant data. This was the case for two of the fields I was trying to access. The issue is trying to dynamically generate the tables.
Q: Does the array have a size?
A: I've looped through in scriban with just the size spitting out. There are 5 tables.
Q: Did you do research?
A: Yes, here are some people on github telling people the issue has been fixed
Does Scriban support .NET Object Indexers?
Accessing object property using indexer notation
Your issue is actually to do with the index out of bounds. You are looping through 0 - the size of the table. In other words, the object is null because you are trying to access past the last entry. I created some super simple POCOs to fill out the objects similar to your code.
public class Document
{
public Data TemplateData { get; set; }
}
public class Data
{
public List<TableRow> Tables { get; set; }
}
public class TableRow
{
public string DataMatrix { get; set; }
}
Here is the updated script to loop through the tables
var bodyTextSub = #"{{~for index in 1..document.template_data.tables.size ~}}
{{index - 1}}: {{ document.template_data.tables[index-1].data_matrix }}
{{ end }}";
var doc = new Document
{
TemplateData = new Data
{
Tables = new List<TableRow>
{
new TableRow {DataMatrix = "This works!!"},
new TableRow {DataMatrix = "Row 2"},
new TableRow {DataMatrix = "Row 3"},
new TableRow {DataMatrix = "Row 4"},
new TableRow {DataMatrix = "Row 5"}
}
}
};
var template2 = Template.Parse(bodyTextSub);
var result2 = template2.Render(new {document = doc});
Console.WriteLine(result2);
Here is the result:
0: This works!!
1: Row 2
2: Row 3
3: Row 4
4: Row 5

Need a string value on an Attribute on my HDF5 File

i am trying to add some attributes on my datasets and it is working fine, but i have one problem when writing the value of the attributes, i need them to be a string, not a INT nor float or whatever, every tutorial i find on the internet uses a int value for those attributes..
I've tried a lot of different things and none of them works well and the code is becoming very ugly, this is my code:
foreach (BasicVariable bv in pf.basicVariableList.bvList)
{
H5DataSetId dataSetId = H5D.create(bvGroupId, bv.bvTag, typeId, spaceId);
bv.atribList.Add(new Atribbs("Eng. Unit", "Temperatura"));
bv.atribList.Add(new Atribbs("Atrib2", "Teste"));
foreach(Atribbs a in bv.atribList )
{
H5DataTypeId auxDT = H5T.copy(H5T.H5Type.C_S1);
H5T.setSize(auxDT, H5T.getSize(H5T.H5Type.C_S1));
const int auxData = 2;
long[] auxDim = new long[1];
auxDim[0] = 1;
H5DataSpaceId auxDS = H5S.create_simple(1, auxDim);
var attr_id = H5A.create(dataSetId, a.attName, auxDT, auxDS);
byte[] bytes = Encoding.UTF8.GetBytes(a.valueStr);
var atrData = new string[] { Encoding.Default.GetString(bytes)};
H5A.write<string>(attr_id, auxDT, new H5Array<string>(atrData));
H5A.close(attr_id);
}
H5D.close(dataSetId);
}
H5F.close(fileId);
The attributes i've created are "Eng. Unit" and "Atrib2" and that is working fine, the problem is thet the "Eng. Unit" should have the "Temperatura" value and "Atrib2" should have "Teste" as it's value, this is what i get on the hdfl viewer
enter image description here
enter image description here
Maybe you want to have a look at HDFql, which greatly simplifies how HDF5 files are handled. Here goes a solution using HDFql in C# (assume that the HDF5 file is named test.h5 and the dataset is named dset):
HDFql.Execute("USE FILE test.h5"); // use (i.e. open) HDF5 file "test.h5"
HDFql.Execute("CREATE ATTRIBUTE \"dset/Eng. Unit\" AS VARCHAR VALUES(Temperatura)"); // create attribute "Eng. Unit" in dataset "dset" with an initial value of "Temperatura"
HDFql.Execute("CREATE ATTRIBUTE dset/Atrib2 AS VARCHAR VALUES(Teste)"); // create attribute "Atrib2" in dataset "dset" with an initial value of "Teste"

Pass in an array of PaymentDetailsItemType to PayPalAPI

I am using the PayPal sandbox in ASP.Net C# 4.0. I added the following web reference:
https://www.paypalobjects.com/wsdl/PayPalSvc.wsdl
If i have 1 item (gimme 2 t-shirts please) i can pass it to the PayPal object and complete my transactions with no problems whatsoever:
var item = new PayPalAPIHelper.PayPalWS.PaymentDetailsItemType
{
Quantity = 2, //etc...etc
};
var paymentDetails = new PayPalAPIHelper.PayPalWS.PaymentDetailsType();
paymentDetails.PaymentDetailsItem = new PaymentDetailsItemType[]{item};
Now my dilemma is when a customer wants different items (1 t-shirt, 1 pair of pants). Now i need multiple PaymentDetailsItemType objects to pass to the paymentDetails object. I tried this:
//now i have an array of different items
var items = new PayPalAPIHelper.PayPalWS.PaymentDetailsItemType[3];
items[0].Description = "T-shirt";
items[1].Description = "Jeans";
paymentDetails.PaymentDetailsItem = new PaymentDetailsItemType[]{items};
I get this error:
Cannot implicitly convert type 'PayPalAPIHelper.PayPalWS.PaymentDetailsItemType[]'
to 'PayPalAPIHelper.PayPalWS.PaymentDetailsItemType'
I can do this and it compiles:
paymentDetails.PaymentDetailsItem = new PaymentDetailsItemType[]{items[0],items[1]};
But when I run it, i get Data type '' mismatch in element 'Quantity' when i call the PayPal service:
PayPalAPIHelper.PayPalWS.PaymentDetailsType paymentDetails = new PayPalAPIHelper.PayPalWS.PaymentDetailsType();
paymentDetails.PaymentDetailsItem = new PayPalAPIHelper.PayPalWS.PaymentDetailsItemType[] { items[0],items[1] };
reqDetails.PaymentDetails = new PayPalAPIHelper.PayPalWS.PaymentDetailsType[] { paymentDetails };
PayPalAPIHelper.PayPalWS.SetExpressCheckoutReq req = new PayPalAPIHelper.PayPalWS.SetExpressCheckoutReq()
{
SetExpressCheckoutRequest = new PayPalAPIHelper.PayPalWS.SetExpressCheckoutRequestType()
{
Version = Version,
SetExpressCheckoutRequestDetails = reqDetails
}
};
// query PayPal and get token
//error occurs here
PayPalAPIHelper.PayPalWS.SetExpressCheckoutResponseType resp = BuildPayPalWebservice().SetExpressCheckout(req); //this is where the error occurs
How do i pass multiple types to the PayPal API web service so the user can order different items? Thanks in advance
First, you already have an array, so it makes no sense to create a new one just for the sake of assignment into paymentDetails.PaymentDetailsItem:
var items = new PayPalAPIHelper.PayPalWS.PaymentDetailsItemType[3];
…
paymentDetails.PaymentDetailsItem = items; // this is wrong: new PaymentDetailsItemType[]{items};
By writing new PaymentDetailsItemType[]{items} you create a new array and try to initialize its first item (of type PaymentDetailsItemType) with the contents of another array items (of type PaymentDetailsItemType[] — hence incompatible).
Second, make sure you fill all required properties for all items in the array. Most likely, in your example of one t-shirt and one jeans you should do:
items[0].Description = "T-shirt";
items[0].Quantity = 1;
items[1].Description = "Jeans";
items[1].Quantity = 1;

Doubled tags for one property in ROWLEX

I have this code:
[RdfSerializable( HasResourceUri=false )]
public class Item
{
[RdfProperty(true)]
public string MyProp;
}
[RdfSerializable]
public class AllItems
{
[RdfProperty(true)] public string mTitle;
private int id = new Random().Next(0, 20);
[ResourceUri]
public string ResourceUri
{
get { return "This " + id.ToString(); }
}
[RdfProperty(false, Name="item")]
public Item[] Items;
}
Created this way:
var item = new AllItems();
item.mTitle = "Hello World!";
item.Items = new Item[] { new Item() { MyProp = "test1" }, new Item() { MyProp = "test2" } };
var doc = Rdfizer.Serialize(item);
System.Console.Out.Write(doc.ToString());
Here is a part of the result:
<ns:AllItems rdf:about="This 1">
<ns:mTitle rdf:datatype="http://www.w3.org/2001/XMLSchema#string
">Hello World!</ns:mTitle>
<ns:item>
<ns:Item>
<ns:MyProp rdf:datatype="http://www.w3.org/2001/
XMLSchema#string">test1</ns:MyProp>
</ns:Item>
</ns:item>
<ns:item>
<ns:Item>
<ns:MyProp rdf:datatype="http://www.w3.org/2001/
XMLSchema#string">test2</ns:MyProp>
</ns:Item>
</ns:item>
</ns:AllItems>
First question is: How could I make and be a single tag?
Second question: How could I make tag not visible, but only its content? i.e. all of its children to be direct children of tag.
In short: what you want violates RDF specs. It looks like you would like to treat the output as XML, but you shouldn't!
In RDF, you manipulate the triples and you should never ever care how it is serialized into XML, because RDF is syntax independent and RDF/XML serialization specs allows to represent the same set of triples many different way. To illustrate it, you might pick RDF Tool "A" create an RDF document. You pick RDF Tool "B", load that document and save it under a new name again without any modification. You compare the two files and you will find the same triples inside but the two XML files might look quite different! You cannot make tags come and go, actually tags are "not your business" :).
The bottomline is, if you want to dictate how your output XML should look like, you should just forget RDF completely and just use plain old XML tools to do get the job done.

Categories

Resources