#c# #.net #xml #linq-to-xml
#c# #.net #xml #linq-to-xml
Вопрос:
У меня есть XML-файл, подобный:
<myPrefix:Catalog xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:myPrefix="clr-namespace:........">
<myPrefix:Item Name="Item1" Mode="All" />
<myPrefix:Item Name="Item2" Mode="Single" />
</myPrefix:Catalog>
С помощью C # я создаю новый элемент, подобный:
XContainer container = XElement.Parse(xml);
XElement xmlTree =
new XElement("Item",
new XAttribute("Name", item.Name),
new XAttribute("Mode", item.Mode));
Как вы можете видеть, я не добавляю префикс «myPrefix». Кто-нибудь может сказать мне, как я могу это сделать? Я не хочу снова объявлять xmlns. Спасибо, Питер
Ответ №1:
XElement container = XElement.Parse(xml);
XNamespace myPrefix = container.GetNamespaceOfPrefix("myPrefix");
XElement xmlTree = new XElement(myPrefix "Item",
new XAttribute("Name", item.Name),
new XAttribute("Mode", item.Mode));
container.Add(xmlTree);
Ответ №2:
Редактировать 1:
Если вы добавите атрибут пространства имен также к элементу, это заставит его добавить префикс. Но в конечном итоге вы все равно получаете атрибут xmlns в узле. Чтобы удалить его, вам, вероятно, как говорит Джефф, потребуется использовать XmlWriter.
Правка 2:
Чтобы получить ТОЧНЫЙ XML, который вы хотите, вам также необходимо создать корневой элемент:
Правка 3:
ОК. Я нашел способ получить то, что вы хотите, без XmlWriter:
var xml = "<myPrefix:Catalog xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:sys="clr-namespace:System;assembly=mscorlib" xmlns:myPrefix="clr-namespace:........"><myPrefix:Item Name="Item1" Mode="All" /></myPrefix:Catalog>";
XNamespace presentation = "http://schemas.microsoft.com/winfx/2006/xaml/presentation";
XNamespace xaml = "http://schemas.microsoft.com/winfx/2006/xaml";
XNamespace mscorlib = "clr-namespace:System;assembly=mscorlib";
XNamespace myPrefix = "clr-namespace:.......";
XElement container = XElement.Parse(xml);
var xmlTree = new XElement("Item",
new XAttribute("Name", "Item2"),
new XAttribute("Mode", "Single"));
container.Add(xmlTree);
foreach (var el in container.DescendantsAndSelf())
{
el.Name = myPrefix.GetName(el.Name.LocalName);
var atList = el.Attributes().ToList();
el.Attributes().Remove();
foreach (var at in atList)
{
if (el.Name.LocalName == "Catalog" amp;amp; at.Name.LocalName != "xmlns")
continue;
el.Add(new XAttribute(at.Name.LocalName, at.Value));
}
}
container.Add(new XAttribute(XNamespace.Xmlns "x", xaml));
container.Add(new XAttribute(XNamespace.Xmlns "sys", mscorlib));
container.Add(new XAttribute(XNamespace.Xmlns "myPrefix", myPrefix));
Правка 4:
Очевидно, был более простой способ … намного проще… смотрите другие ответы.
Комментарии:
1. Спасибо за ваш ответ, но это не сработает. Результат выглядит следующим образом: <Имя элемента=»Item3″ Mode=»Single» xmlns=»clr-пространство имен:…….» />
2. @Peter: Это будет выглядеть именно так, если элемент является корневым. Если это не корень, то у него будет префикс, если пространство имен объявлено в предке.
3. @Peter: Именно так работает сериализатор LINQ to XML. Я не знаю, возможно ли это вообще, не возвращаясь назад и не используя
XmlWriter
.4. @Джефф, хм, спасибо, хорошо. Может быть, кто-нибудь знает способ, и я попробую XmlWriter.
5. @Sani большое спасибо! У меня это работает 🙂 Теперь мне нужно только удалить xmlns.
Ответ №3:
Вам необходимо создать любые новые элементы в пространстве имен. Предполагая, что вы знаете префикс пространства имен, которое вы хотите использовать в образце XML, тогда сделайте это следующим образом:
var xml = "<myPrefix:Catalog xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:sys="clr-namespace:System;assembly=mscorlib" xmlns:myPrefix="clr-namespace:........"><myPrefix:Item Name="Item1" Mode="All" /></myPrefix:Catalog>";
XElement catalog = XElement.Parse(xml);
XNamespace myP = catalog.GetNamespaceOfPrefix("myPrefix");
catalog.Add(new XElement(myP "Item", new XAttribute("Name", "foo"), new XAttribute("Mode", "bar")));