मेरे पास LINQ to XML iqnore सभी नामस्थान कैसे हैं? या बदलकर, मैं कैसे नामस्थानों को छीन सकता हूं?
मैं पूछ रहा हूं क्योंकि नामस्थान एक अर्ध-यादृच्छिक फैशन में सेट किए जा रहे हैं और मैं बिना नाम के दोनों के साथ नोड्स की खोज करने के लिए थक गया हूं।
मेरे पास LINQ to XML iqnore सभी नामस्थान कैसे हैं? या बदलकर, मैं कैसे नामस्थानों को छीन सकता हूं?
मैं पूछ रहा हूं क्योंकि नामस्थान एक अर्ध-यादृच्छिक फैशन में सेट किए जा रहे हैं और मैं बिना नाम के दोनों के साथ नोड्स की खोज करने के लिए थक गया हूं।
जवाबों:
लिखने के बजाय:
nodes.Elements("Foo")
लिखो:
nodes.Elements().Where(e => e.Name.LocalName == "Foo")
और जब आप इससे थक जाते हैं, तो अपनी खुद की एक्सटेंशन विधि बनाएं:
public static IEnumerable<XElement> ElementsAnyNS<T>(this IEnumerable<T> source, string localName)
where T : XContainer
{
return source.Elements().Where(e => e.Name.LocalName == localName);
}
विशेषताओं के लिए डिट्टो, यदि आपको अक्सर नामांकित विशेषताओं से निपटना पड़ता है (जो अपेक्षाकृत दुर्लभ है)।
XPath के लिए, लिखने के बजाय:
/foo/bar | /foo/ns:bar | /ns:foo/bar | /ns:foo/ns:bar
आप local-name()
फ़ंक्शन का उपयोग कर सकते हैं :
/*[local-name() = 'foo']/*[local-name() = 'bar']
xDoc.Root.Descendants().Where(e => e.Name.LocalName == "SomeName");
यहां नामस्थानों को पट्टी करने की एक विधि दी गई है:
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;
}
उदाहरण उपयोग:
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);
जैसा कि मैंने विशेषताओं पर नामस्थानों को अनदेखा करने के आसान तरीके की तलाश में यह प्रश्न पाया, यहाँ एक विशेषता तक पहुँचने पर नामस्थानों की अनदेखी करने के लिए एक एक्सटेंशन है, जो पावेल्स के उत्तर पर आधारित है (आसान प्रतिलिपि के लिए, मैंने उनका एक्सटेंशन शामिल किया है):
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);
}