XSD2Code namespace issue - xml-serialization

I am using XSD2Code to generate C# class from XSD file.
I got stuck with the following problem.
XML file looks something like
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Notification xmlns="http://message.domain.com">
<Object xmlns="http://type.domain.com" ID="97440" />
</Notification>
XML gets succefsully deserialized when xmls for Object is empty. But when there is a value like in the sample above, I get an error "Object reference not set to an instance of an object".
What could cause this error?

you have to change the Serializer to something like that
private static System.Xml.Serialization.XmlSerializer Serializer
{
get
{
if ((serializer == null))
{
serializer = new System.Xml.Serialization.XmlSerializer(typeof(Notification), "http://message.domain.com");
}
return serializer;
}
}

To turn off encoding, disable encoding on the Serialization tab

Related

Why does CanDeserialize always return false when deserialization succeeds?

I am attempting to deserialize an xml string into an object, nothing strange about that. Everything was fine until I upgraded my project to .Net5.
In the upgrade, I had to add a reference to the package Microsoft.XmlSerializer.Generator, and alter the project file to add the following:
<ItemGroup>
<DotNetCliToolReference Include="Microsoft.XmlSerializer.Generator" Version="1.0.0" />
</ItemGroup>
That allowed me to create the XmlSerializer (first error was just weird). Now, however, every call to CanDeserialize on the XmlReader return false if the class has the XmlRoot attribute. Now, I can deserialize the xml text. That does work. But why would CanDeserialize fail based on that condition?
Below is the class and the code I am using to test in a console app (.Net5).
[Serializable, XmlRoot("TestObj")]
//[Serializable]
public class TestObj
{
public int TestVal;
}
static void Main(string[] args)
{
var serializer = new XmlSerializer(typeof(TestObj));
//generated by doing a test serialization of the class
var teststr = "<TestObj xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"><TestVal>2</TestVal></TestObj>";
using (var str = new StringReader(teststr))
using (var reader = XmlReader.Create(str))
{
if (serializer.CanDeserialize(reader))
Console.WriteLine(((TestObj)serializer.Deserialize(reader)).TestVal);
else
{
Console.WriteLine("Value cannot be deserialized into the given Type");
//try it anyway
var o = (TestObj)serializer.Deserialize(reader);
Console.WriteLine(o.TestVal);
}
}
}
My workaround is just to eliminate the CanDeserialize call and wrap the deserialization in a try.. catch, but I'm still curious why this is happening.
Okay, comments on the question from #dbc did lead me to try something else. A couple of details I left of the original question because it didn't seem relevant (due to the testing involved) is that the class I am trying to deserialize in my non-test is in a .Net Standard 2.1 library. While the project doing the deserialization is .Net5.
In the end, I got this work. I had to reference the Microsoft.XmlSerializer.Generator package in my .Net Standard based library, but not reference it in the .Net5 project.
In short, leaving the package reference off the Standard project caused one error, and including it in both caused another.

XMLSerialization issue

I need to generate the XML file which will be consumed by the external application. And I have observed that it depends on ordering of the namespace defined in the XML. Since the xml is consumed by external application, I don't have the exact error details.
Below is the sample code
[System.CodeDom.Compiler.GeneratedCodeAttribute("Xsd2Code", "3.4.0.32990")]
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://mycompany.com/2010/package")]
[System.Xml.Serialization.XmlRootAttribute("Catalog", Namespace="http://mycompany.com/2010/package", IsNullable=false)]
public partial class PackageT : System.ComponentModel.INotifyPropertyChanged {
}
Extension class written in order to include custom schemalocation
public partial class PackageT
{
[XmlAttributeAttribute("schemaLocation", Namespace = "http://www.w3.org/2001/XMLSchema-instance")]
public string xsiSchemaLocation = "http://mycompany.com/2010/catalog.xsd";
}
Code to serialize the object to XML
XmlSerializerNamespaces namespaces = new XmlSerializerNamespaces();
namespaces.Add("xml", "http://www.w3.org/XML/1998/namespace");
namespaces.Add("test", "http://mycompany.com/2010/package");
XmlSerializer serializer = new XmlSerializer(typeof(PackageT));
TextWriter writer = new StreamWriter("package.xml");
serializer.Serialize(writer, catalog, namespaces);
writer.Flush();
writer.Close();
Generated XML ( not working)
<?xml version="1.0" encoding="utf-8"?>
<test:Catalog
xmlns:xml="http://www.w3.org/XML/1998/namespace"
d1p1:schemaLocation="http://mycompany.com/2010/catalog.xsd"
xmlns:d1p1="http://www.w3.org/2001/XMLSchema-instance" xmlns:test="http://mycompany.com/2010/package">
....
</test:Catalog>
EXpected XML which is working
<?xml version="1.0" encoding="utf-8"?>
<test:Catalog d1p1:schemaLocation="http://mycompany.com/2010/catalog.xsd"
xmlns:xml="http://www.w3.org/XML/1998/namespace"
xmlns:d1p1="http://www.w3.org/2001/XMLSchema-instance" xmlns:test="http://mycompany.com/2010/package">
....
</test:Catalog>
Please help me!!
If you specify the element name and namespace for the root you can generate the XML you're looking for. Modify PackageT as below:
[XmlRoot(ElementName = "Catalog", Namespace = "http://mycompany.com/2010/package") ]
public partial class PackageT
{
[XmlAttribute("schemaLocation", Namespace = "http://www.w3.org/2001/XMLSchema-instance")]
public string xsiSchemaLocation = "http://mycompany.com/2010/catalog.xsd";
}
and the output becomes:
<?xml version="1.0" encoding="utf-8"?>
<test:Catalog xmlns:xml="http://www.w3.org/XML/1998/namespace"
d1p1:schemaLocation="http://mycompany.com/2010/catalog.xsd"
xmlns:d1p1="http://www.w3.org/2001/XMLSchema-instance"
xmlns:test="http://mycompany.com/2010/package" />

Mule ESB: how to filter emails based on subject or sender?

I am new to Mule 3.3 and I am trying to use it to retrieve emails from a POP3 server and download the CSV attachments if the sender field and subject field contain certain keywords. I have used the example provided on Mulesoft website and I have successfully managed to scan my inbox for new emails and only download CSV attachments. However, I am now stuck because I can't figure out how to filter emails by subject and sender fields.
Doing some research I have come across a message-property-filter pattern tag that can be applied to an endpoint, but I am not sure exactly to which endpoint to apply it, incoming or outgoing. Neither approach seems to work and I can't find a decent example showing how to use this tag. The basic algorithm I want to implement is as follows:
if email is from "Bob"
if attachment of type "CSV"
then download CSV attachment
if email subject field contains "keyword"
if attachment of type CSV
then download CSV attachment
Here's the Mule xml I have so far:
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns:file="http://www.mulesoft.org/schema/mule/file" xmlns:pop3s="http://www.mulesoft.org/schema/mule/pop3s" xmlns:pop3="http://www.mulesoft.org/schema/mule/pop3"
xmlns="http://www.mulesoft.org/schema/mule/core"
xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
xmlns:spring="http://www.springframework.org/schema/beans" version="CE-3.3.1"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="
http://www.mulesoft.org/schema/mule/pop3s http://www.mulesoft.org/schema/mule/pop3s/current/mule-pop3s.xsd
http://www.mulesoft.org/schema/mule/file http://www.mulesoft.org/schema/mule/file/current/mule-file.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/pop3 http://www.mulesoft.org/schema/mule/pop3/current/mule-pop3.xsd ">
<expression-transformer expression="#[attachments-list:*.csv]"
name="returnAttachments" doc:name="Expression">
</expression-transformer>
<pop3s:connector name="POP3Connector"
checkFrequency="5000"
deleteReadMessages="false"
defaultProcessMessageAction="RECENT"
doc:name="POP3"
validateConnections="true">
</pop3s:connector>
<file:connector name="fileName" doc:name="File">
<file:expression-filename-parser />
</file:connector>
<flow name="incoming-orders" doc:name="incoming-orders">
<pop3s:inbound-endpoint user="my_username"
password="my_password"
host="pop.gmail.com"
port="995"
transformer-refs="returnAttachments"
doc:name="GetMail"
connector-ref="POP3Connector"
responseTimeout="10000"/>
<collection-splitter doc:name="Collection Splitter"/>
<echo-component doc:name="Echo"/>
<file:outbound-endpoint path="/attachments"
outputPattern="#[function:datestamp].csv"
doc:name="File" responseTimeout="10000">
<expression-transformer expression="payload.inputStream"/>
<message-property-filter pattern="from=(.*)(bob#email.com)(.*)" caseSensitive="false"/>
</file:outbound-endpoint>
</flow>
What is the best way to tackle this problem?
Thanks in advance.
To help you, here are two configuration bits:
The following filter accepts only messages where fromAddress is 'Bob' and where subject contains 'keyword':
<expression-filter
expression="#[message.inboundProperties.fromAddress == 'Bob' || message.inboundProperties.subject contains 'keyword']" />
The following transformer extracts all the attachments whose names end with '.csv':
<expression-transformer
expression="#[($.value in message.inboundAttachments.entrySet() if $.key ~= '.*\\.csv')]" />
Welcome to Mule! A few month ago I implemented a similar proejct for a customer. I take a look at your flow, let´s start refactoring.
Remove the transformer-refs="returnAttachments" from inbound-endpoint
Add the following elements to your flow
<pop3:inbound-endpoint ... />
<custom-filter class="com.benasmussen.mail.filter.RecipientFilter">
<spring:property name="regex" value=".*bob.bent#.*" />
</custom-filter>
<expression-transformer>
<return-argument expression="*.csv" evaluator="attachments-list" />
</expression-transformer>
<collection-splitter doc:name="Collection Splitter" />
Add my RecipientFilter as java class to your project. All messages will be discard if they don't match to the regex pattern.
package com.benasmussen.mail.filter;
import java.util.Collection;
import java.util.Set;
import java.util.regex.Pattern;
import org.mule.api.MuleMessage;
import org.mule.api.lifecycle.Initialisable;
import org.mule.api.lifecycle.InitialisationException;
import org.mule.api.routing.filter.Filter;
import org.mule.config.i18n.CoreMessages;
import org.mule.transport.email.MailProperties;
public class RecipientFilter implements Filter, Initialisable
{
private String regex;
private Pattern pattern;
public boolean accept(MuleMessage message)
{
String from = message.findPropertyInAnyScope(MailProperties.FROM_ADDRESS_PROPERTY, null);
return isMatch(from);
}
public void initialise() throws InitialisationException
{
if (regex == null)
{
throw new InitialisationException(CoreMessages.createStaticMessage("Property regex is not set"), this);
}
pattern = Pattern.compile(regex);
}
public boolean isMatch(String from)
{
return pattern.matcher(from).matches();
}
public void setRegex(String regex)
{
this.regex = regex;
}
}
The mule expression framework is powerful, but in some use cases I prefer my own business logic.
Improvment
Use application properties (mule-app.properties) > mule documentation
Documentation
MailProperties shows you all available message properties (EMail)
Take a look at the mule schema doc to see all available elements
Incoming payload (mails, etc) are transported by an DefaultMuleMessage (Payload, Properties, Attachments)

Drools Planner has trouble creating a configurer: how to debug

I tried to create a solver from XML configuration. But the entire process returns a cryptic error message that makes no sense.
How do I fix this? And how can I make sense of this to actually solve similar problems like this?
jesvin#Jesvin-Technovia:~/dev/drools/sudoku$ java App
Exception in thread "main" java.lang.NullPointerException
at org.drools.planner.core.domain.solution.SolutionDescriptor.processPropertyAnnotations(SolutionDescriptor.java:69)
at org.drools.planner.core.domain.solution.SolutionDescriptor.<init>(SolutionDescriptor.java:61)
at org.drools.planner.config.solver.SolverConfig.buildSolutionDescriptor(SolverConfig.java:197)
at org.drools.planner.config.solver.SolverConfig.buildSolver(SolverConfig.java:167)
at org.drools.planner.config.XmlSolverConfigurer.buildSolver(XmlSolverConfigurer.java:103)
at App.createSolver(App.java:62)
at App.main(App.java:40)
The function that throws it is listed here. The line is of course return configurer.buildSolver();.
private static Solver createSolver(){
XmlSolverConfigurer configurer = new XmlSolverConfigurer();
File file = new File("solver.xml");
FileInputStream fin = null;
try{
fin = new FileInputStream(file);
}
catch(IOException e){
System.out.println("Unable to read drl");
}
configurer.configure(fin);
//configurer.configure("/home/jesvin/dev/drools/sudoku/solver.xml");
return configurer.buildSolver();
}
The content of the XML:
<?xml version="1.0" encoding="UTF-8"?>
<solver>
<environmentMode>DEBUG</environmentMode>
<solutionClass>domain.Sudoku</solutionClass>
<planningEntityClass>domain.Digit</planningEntityClass>
<scoreDrl>score.drl</scoreDrl>
<scoreDefinition>
<scoreDefinitionType>SIMPLE</scoreDefinitionType>
</scoreDefinition>
<termination>
<scoreAttained>0</scoreAttained>
</termination>
<!--
<constructionHeuristic>
<constructionHeuristicType>FIRST_FIT_DECREASING</constructionHeuristicType>
<constructionHeuristicPickEarlyType>FIRST_LAST_STEP_SCORE_EQUAL_OR_IMPROVING</constructionHeuristicPickEarlyType>
</constructionHeuristic> -->
<constructionHeuristic>
<constructionHeuristicType>FIRST_FIT</constructionHeuristicType>
<moveFactoryClass>solution.RowChangeMoveFactory</moveFactoryClass>
</selector>
<acceptor>
<completeSolutionTabuSize>1000</completeSolutionTabuSize>
</acceptor>
<forager>
<!-- Real world problems require to use of <minimalAcceptedSelection> -->
</forager>
</localSearch>
</solver>
OP's addition:
The issue was related to an inadvertent write-only property. There was setBlockList and getBlocklist (small 'l' in the getter), which was a typo. Drools complained because it detected two properties, one of which was write-only.
The other mismatch was isFixed and setFixed. It works for boolean built-in, but not for Boolean object.
I solved the issue in a mailing list post.
Cryptic error message is fixed in 5.4.0.Beta1 (already released): https://issues.jboss.org/browse/JBRULES-3247

Can XmlSerializer deserialize into a Nullable<int>?

I wanted to deserialize an XML message containing an element that can be marked nil="true" into a class with a property of type int?. The only way I could get it to work was to write my own NullableInt type which implements IXmlSerializable. Is there a better way to do it?
I wrote up the full problem and the way I solved it on my blog.
I think you need to prefix the nil="true" with a namespace in order for XmlSerializer to deserialise to null.
MSDN on xsi:nil
<?xml version="1.0" encoding="UTF-8"?>
<entities xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="array">
<entity>
<id xsi:type="integer">1</id>
<name>Foo</name>
<parent-id xsi:type="integer" xsi:nil="true"/>
My fix is to pre-process the nodes, fixing any "nil" attributes:
public static void FixNilAttributeName(this XmlNode #this)
{
XmlAttribute nilAttribute = #this.Attributes["nil"];
if (nilAttribute == null)
{
return;
}
XmlAttribute newNil = #this.OwnerDocument.CreateAttribute("xsi", "nil", "http://www.w3.org/2001/XMLSchema-instance");
newNil.Value = nilAttribute.Value;
#this.Attributes.Remove(nilAttribute);
#this.Attributes.Append(newNil);
}
I couple this with a recursive search for child nodes, so that for any given XmlNode (or XmlDocument), I can issue a single call before deserialization. If you want to keep the original in-memory structure unmodified, work with a Clone() of the XmlNode.
The exceptionally lazy way to do it. It's fragile for a number of reasons but my XML is simple enough to warrant such a quick and dirty fix.
xmlStr = Regex.Replace(xmlStr, "nil=\"true\"", "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:nil=\"true\"");