Jika Anda mengetahui bahwa elemen yang Anda inginkan dinamai secara unik, Anda dapat melewati semua elemen perantara dengan:xDoc.Root.Descendants().Where(e => e.Name.LocalName == "SomeName");
AaronLS
17
Berikut metode untuk menghapus ruang nama:
private static XElement StripNamespaces(XElement rootElement)
{
foreach (var element in rootElement.DescendantsAndSelf())
{
// update element name if a namespace is available
if (element.Name.Namespace != XNamespace.None)
{
element.Name = XNamespace.None.GetName(element.Name.LocalName);
}
// check if the element contains attributes with defined namespaces (ignore xml and empty namespaces)
bool hasDefinedNamespaces = element.Attributes().Any(attribute => attribute.IsNamespaceDeclaration ||
(attribute.Name.Namespace != XNamespace.None && attribute.Name.Namespace != XNamespace.Xml));
if (hasDefinedNamespaces)
{
// ignore attributes with a namespace declaration
// strip namespace from attributes with defined namespaces, ignore xml / empty namespaces
// xml namespace is ignored to retain the space preserve attribute
var attributes = element.Attributes()
.Where(attribute => !attribute.IsNamespaceDeclaration)
.Select(attribute =>
(attribute.Name.Namespace != XNamespace.None && attribute.Name.Namespace != XNamespace.Xml) ?
new XAttribute(XNamespace.None.GetName(attribute.Name.LocalName), attribute.Value) :
attribute
);
// replace with attributes result
element.ReplaceAttributes(attributes);
}
}
return rootElement;
}
Contoh penggunaan:
XNamespace ns = "http://schemas.domain.com/orders";
XElement xml =
new XElement(ns + "order",
new XElement(ns + "customer", "Foo", new XAttribute("hello", "world")),
new XElement("purchases",
new XElement(ns + "purchase", "Unicycle", new XAttribute("price", "100.00")),
new XElement("purchase", "Bicycle"),
new XElement(ns + "purchase", "Tricycle",
new XAttribute("price", "300.00"),
new XAttribute(XNamespace.Xml.GetName("space"), "preserve")
)
)
);
Console.WriteLine(xml.Element("customer") == null);
Console.WriteLine(xml);
StripNamespaces(xml);
Console.WriteLine(xml);
Console.WriteLine(xml.Element("customer").Attribute("hello").Value);
Ketika saya menemukan pertanyaan ini dalam mencari cara mudah untuk mengabaikan ruang nama pada atribut, berikut adalah ekstensi untuk mengabaikan ruang nama saat mengakses atribut, berdasarkan jawaban Pavel (untuk penyalinan yang lebih mudah, saya menyertakan ekstensinya):
public static XAttribute AttributeAnyNS<T>(this T source, string localName)
where T : XElement
{
return source.Attributes().SingleOrDefault(e => e.Name.LocalName == localName);
}
public static IEnumerable<XElement> ElementsAnyNS<T>(this IEnumerable<T> source, string localName)
where T : XContainer
{
return source.Elements().Where(e => e.Name.LocalName == localName);
}
Jawaban:
Alih-alih menulis:
menulis:
dan ketika Anda bosan, buat metode ekstensi Anda sendiri:
public static IEnumerable<XElement> ElementsAnyNS<T>(this IEnumerable<T> source, string localName) where T : XContainer { return source.Elements().Where(e => e.Name.LocalName == localName); }
Ditto untuk atribut, jika Anda harus sering berurusan dengan atribut namespace (yang relatif jarang).
[EDIT] Menambahkan solusi untuk XPath
Untuk XPath, alih-alih menulis:
Anda dapat menggunakan
local-name()
fungsi:sumber
xDoc.Root.Descendants().Where(e => e.Name.LocalName == "SomeName");
Berikut metode untuk menghapus ruang nama:
Contoh penggunaan:
sumber
Ketika saya menemukan pertanyaan ini dalam mencari cara mudah untuk mengabaikan ruang nama pada atribut, berikut adalah ekstensi untuk mengabaikan ruang nama saat mengakses atribut, berdasarkan jawaban Pavel (untuk penyalinan yang lebih mudah, saya menyertakan ekstensinya):
public static XAttribute AttributeAnyNS<T>(this T source, string localName) where T : XElement { return source.Attributes().SingleOrDefault(e => e.Name.LocalName == localName); } public static IEnumerable<XElement> ElementsAnyNS<T>(this IEnumerable<T> source, string localName) where T : XContainer { return source.Elements().Where(e => e.Name.LocalName == localName); }
sumber