Где моя XDeclaration?
По какой-то причине следующий код создает XML, который не содержит объявления:
XDocument xDocument = new XDocument(new XDeclaration("1.0", "utf-8", "yes"),
new XElement("project",
new XAttribute("number", project.ProjectNumber),
new XElement("store",
new XAttribute("number", project.StoreNumber)
),
// User Element
new XElement("user",
new XAttribute("owner-id", project.OwnerID ?? 0),
new XElement("email", new XCData(project.OwnerEmail ?? "")),
new XElement("project-name", new XCData(project.ProjectName ?? ""))
),
// Nested Project Element
new XElement("nested-project",
new XAttribute("version", new Version(1, 0)),
new XElement("project",
new XAttribute("version", new Version(1, 0)),
xProjectItems = new XElement("project-items")
),
new XElement("price-per-part", project.PricePerPart),
new XElement("sheet-quantity", project.SheetQuantity),
new XElement("edge-length", project.EdgeLength),
new XElement("price", project.Price),
new XElement("status", project.Status),
xMaterialItems = new XElement("alternative-material-items"),
xProductItems = new XElement("project-product-items")
)
)
);
String strXML = xDocument.ToString();
Он сделал выражение раньше. Мне что-то не хватает?
Спасибо.
Ответы
Ответ 1
XDeclaration будет доступен, если вы используете один из методов XDocument.Save
. Например:
var doc = new XDocument (
new XDeclaration ("1.0", "utf-8", "yes"),
new XElement ("test", "data")
);
string path = Path.Combine(Path.GetTempPath(), "temp.xml");
doc.Save(path);
Console.WriteLine(File.ReadAllText(path));
Альтернативно вы можете использовать этот подход:
var sw = new StringWriter();
doc.Save(sw);
string result = sw.GetStringBuilder().ToString();
Console.WriteLine(result);
EDIT: обратите внимание, что некоторые подходы преобразуют обозначение utf-8 в utf-16. Если вы хотите заставить его быть utf-8, вам придется использовать этот другой подход:
using (var mem = new MemoryStream())
using (var writer = new XmlTextWriter(mem, System.Text.Encoding.UTF8))
{
writer.Formatting = Formatting.Indented;
doc.WriteTo(writer);
writer.Flush();
mem.Flush();
mem.Seek(0, SeekOrigin.Begin);
using (var reader = new StreamReader(mem))
{
var xml = reader.ReadToEnd();
Console.WriteLine(xml);
}
}
Ответ 2
Документация не указывает явно, что xDocument.ToString()
выводит объявление XML, оно только говорит: "Возвращает отступы XML для этого node"..
В моем тестировании я обнаружил, что следующие методы выдадут объявление:
Используйте ToString
в свойстве Declaration
:
string strXML = string.Concat(xDocument.Declaration.ToString(), "\r\n",
xDocument.ToString());
или используйте метод Save
:
string strXml;
using(var ms = new MemoryStream())
{
xDocument.Save(ms);
ms.Position = 0;
using(var sr = new StreamReader(ms))
{
strXml = sr.ReadToEnd();
}
}
Ответ 3
Мой ответ (вдохновленный ответом @rsbarro):
string xml = xDocument.Declaration.ToString() +
xDocument.ToString();
- или -
string xml = xDocument.Declaration.ToString() +
xDocument.ToString(SaveOptions.DisableFormatting);
Что касается того, почему я полагаю, что использование оператора +
является подходящим в этой ситуации, см. этот ответ на вопрос Какой лучший метод конкатенации строк с использованием С#?.