XmlSerializer.Serialize Удаление дескриптора <xml>
Я пытаюсь связаться с платежным процессором. Когда я использую XmlSerializer.Serialize
на моем объекте я получаю
<?xml version=\"1.0\" encoding=\"utf-16\"?>
<txn xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">
<ssl_merchant_id>xxxxxx</ssl_merchant_id>
<ssl_user_id>xxxxxx</ssl_user_id>
<ssl_pin>xxxxxx</ssl_pin>
<ssl_test_mode>True</ssl_test_mode>
<ssl_transaction_type>ccavsonly</ssl_transaction_type>
<ssl_card_number>4111111111111111</ssl_card_number>
<ssl_exp_date>0612</ssl_exp_date>
<ssl_avs_address>101 Main St.</ssl_avs_address>
<ssl_avs_zip>90210</ssl_avs_zip>
</txn>
До использования этого метода я вручную построил XML для тестирования, и это сработало:
<txn>
<ssl_merchant_id>xxxxxx</ssl_merchant_id>
<ssl_user_id>xxxxxx</ssl_user_id>
<ssl_pin>xxxxxx</ssl_pin>
<ssl_test_mode>True</ssl_test_mode>
<ssl_transaction_type>ccavsonly</ssl_transaction_type>
<ssl_card_number>4111111111111111</ssl_card_number>
<ssl_exp_date>0612</ssl_exp_date>
<ssl_avs_address>101 Main St.</ssl_avs_address>
<ssl_avs_zip>90210</ssl_avs_zip>
</txn>
Как бы я хотел скомпоновать <?xml version=\"1.0\" encoding=\"utf-16\"?>
и xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">
из XML или не генерировать сериализатор для начала?
Мой объект выглядит так:
[XmlRoot(ElementName="txn")]
public class AvsTransmission
{
[XmlElement]
public string ssl_merchant_id { get; set; }
[XmlElement]
public string ssl_user_id { get; set; }
[XmlElement]
public string ssl_pin { get; set; }
[XmlElement]
public string ssl_test_mode { get; set; }
[XmlElement]
public string ssl_transaction_type { get; set; }
[XmlElement]
public string ssl_card_number { get; set; }
[XmlElement]
public string ssl_exp_date { get; set; }
[XmlElement]
public string ssl_avs_address { get; set; }
[XmlElement]
public string ssl_avs_zip { get; set; }
}
Ответы
Ответ 1
Мой первый ответ был только половиной проблемы, вам также нужно удалить декларацию, как было упомянуто.
Вот пример:
XmlWriterSettings settings = new XmlWriterSettings();
settings.OmitXmlDeclaration = true;
MemoryStream ms = new MemoryStream();
XmlWriter writer = XmlWriter.Create(ms, settings);
XmlSerializerNamespaces names = new XmlSerializerNamespaces();
names.Add("", "");
XmlSerializer cs = new XmlSerializer(typeof(Cat));
cs.Serialize(writer, new Cat { Lives = 9 }, names);
ms.Flush();
ms.Seek(0, SeekOrigin.Begin);
StreamReader sr = new StreamReader(ms);
var xml = sr.ReadToEnd();
Строка xml
теперь содержит:
<cat><Lives>9</Lives></cat>
Ответ 2
Первая функция преобразует объект в строку xml, вторая конвертирует объект и записывает xml в файл одновременно.
public static string Serialize<T>(T obj)
{
XmlWriterSettings settings = new XmlWriterSettings();
settings.OmitXmlDeclaration = true;
var writer = new StringWriter();
XmlWriter xmlWriter = XmlWriter.Create(writer, settings);
XmlSerializerNamespaces names = new XmlSerializerNamespaces();
names.Add("", "");
XmlSerializer serializer = new XmlSerializer(typeof(T));
serializer.Serialize(xmlWriter, obj, names);
var xml = writer.ToString();
return xml;
}
public static void Serialize<T>(T obj, string filepath)
{
XmlWriterSettings settings = new XmlWriterSettings();
settings.OmitXmlDeclaration = true;
var writer = new StreamWriter(filepath);
XmlWriter xmlWriter = XmlWriter.Create(writer, settings);
XmlSerializerNamespaces names = new XmlSerializerNamespaces();
names.Add("", "");
XmlSerializer serializer = new XmlSerializer(typeof(T));
serializer.Serialize(xmlWriter, obj, names);
}
На самом деле я понял, что код повторяется. В этих методах измените только одну вещь, которая является объектом-автором, поэтому код должен выглядеть следующим образом. Таким образом, вы можете легко использовать код, просто изменив тип объекта записи.
public static string Serialize<T>(T obj)
{
var writer = new StringWriter();
Serialize<T>(obj,writer);
var xml = writer.ToString();
return xml;
}
public static void Serialize<T>(T obj, string filepath)
{
var writer = new StreamWriter(filepath);
Serialize<T>(obj,writer);
}
public static void Serialize<T>(T obj, TextWriter writer)
{
XmlWriterSettings settings = new XmlWriterSettings();
settings.OmitXmlDeclaration = true;
XmlWriter xmlWriter = XmlWriter.Create(writer, settings);
XmlSerializerNamespaces names = new XmlSerializerNamespaces();
names.Add("", "");
XmlSerializer serializer = new XmlSerializer(typeof(T));
serializer.Serialize(xmlWriter, obj, names);
}
Ответ 3
Если вы используете XmlWriter, есть параметр, чтобы опустить объявление
http://msdn.microsoft.com/en-us/library/system.xml.xmlwritersettings.omitxmldeclaration.aspx
Я буду работать над примером, но этого может быть достаточно, чтобы вы начали.
EDIT: Здесь образец, который выполняется в LinqPad
string test = "test";
XmlWriterSettings settings = new XmlWriterSettings();
settings.OmitXmlDeclaration = true;
MemoryStream strm = new MemoryStream();
XmlWriter writer = XmlWriter.Create(strm, settings);
XmlSerializer serializer = new XmlSerializer(typeof(string));
serializer.Serialize(writer, test);
strm.Position = 0;
StreamReader reader = new StreamReader(strm);
var x = reader.ReadToEnd();
x.Dump();
writer.Close();
reader.Close();
strm.Close();
Выход
<string>test</string>
Вывод строки вывода 3 и вывод
<?xml version="1.0" encoding="utf-8"?><string>test</string>
Ответ 4
Просто, чтобы упростить soln. оригинальной проблемы удаления декларации кодировки UTF
вот код
StringBuilder sb = new StringBuilder();
var serializer = new System.Xml.Serialization.XmlSerializer(typeToSerialize.GetType());
serializer.Serialize(System.Xml.XmlWriter.Create(sb, new System.Xml.XmlWriterSettings { OmitXmlDeclaration = true, Indent=true }), typeToSerialize);
Ответ 5
Очень похоже на @payo orignal ответ:
Если вы хотите удалить пространство имен, вы также можете удалить эту версию, чтобы сохранить поиск. Я добавил эту функциональность, чтобы нижний код выполнял оба.
Я также обернул его в общий метод, так как я создаю очень большие xml файлы, которые слишком велики для сериализации в памяти, поэтому я сломал свой выходной файл и сериализую его в меньших "кусках":
public string XmlSerialize<T>(T entity) where T : class
{
// removes version
XmlWriterSettings settings = new XmlWriterSettings();
settings.OmitXmlDeclaration = true;
XmlSerializer xsSubmit = new XmlSerializer(typeof(T));
StringWriter sw = new StringWriter();
using (XmlWriter writer = XmlWriter.Create(sw, settings))
{
// removes namespace
var xmlns = new XmlSerializerNamespaces();
xmlns.Add(string.Empty, string.Empty);
xsSubmit.Serialize(writer, entity, xmlns);
return sw.ToString(); // Your XML
}
}