Проигнорируйте пространства имен в LINQ к XML

Вы имеете, "работает на фактическом браузере" как на про, но по моему опыту который является доводом "против", потому что это медленно. Но то, что делает его ценным, является отсутствием достаточной эмуляции JS от альтернатив небраузера. Могло случиться так, что, если Ваш JS достаточно сложен, что только в тесте браузера будет достаточен, но существует пара большего количества опций рассмотреть:

HtmlUnit: "Это имеет довольно хорошую поддержку JavaScript (который постоянно улучшается), и в состоянии работать даже с довольно сложными библиотеками AJAX, моделируя или Firefox или Internet Explorer в зависимости от конфигурации, которую Вы хотите использовать". Если его эмуляция будет достаточно хороша для Вашего использования тогда, то это будет намного быстрее, чем управление браузером.

, Но возможно HtmlUnit имеет достаточно хорошую поддержку JS, но Вам не нравится Java? Тогда, возможно:

Быстрота : API Watir, работающий на JRuby, поддержанном HtmlUnit.

или так же

Schnell: другая обертка JRuby HtmlUnit.

, Конечно, если HtmlUnit не достаточно хорош и необходимо управлять браузером тогда, Вы могли бы полагать Watir управлять своим JS.

83
задан Sadegh 17 July 2009 в 21:06
поделиться

2 ответа

Вместо того, чтобы писать:

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);
}

То же самое для атрибутов, если вам нужно иметь дело с пространством имен атрибуты часто (что довольно редко).

[EDIT] Добавление решения для XPath

Для XPath вместо записи:

/foo/bar | /foo/ns:bar | /ns:foo/bar | /ns:foo/ns:bar

вы можете использовать local-name () функцию:

/*[local-name() = 'foo']/*[local-name() = 'bar']
134
ответ дан 24 November 2019 в 08:52
поделиться

Вот метод удаления пространств имен:

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);
15
ответ дан 24 November 2019 в 08:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: