2010-03-08 2 views
6

Еще одна проблема с возможностями XSD:

Я отправлял XML-файлы моими клиентами, у которых будет 0 или более неопределенных или [вызываемых] неожиданных тегов (может отображаться в иерархии). Ну, это лишние теги для меня .. поэтому я должен игнорировать их присутствие, но вместе с ними есть набор тегов, которые должны быть проверены.Как игнорировать проверку неизвестных тегов?

Это пример XML:

<root> 
    <undefined_1>one</undefined_1> 
    <undefined_2>two</undefined_2> 
    <node>to_be_validated</node> 
    <undefined_3>two</undefined_3> 
    <undefined_4>two</undefined_4> 
</root> 

И XSD я попытался с:

<xs:element name="root" type="root"></xs:element> 
    <xs:complexType name="root"> 
    <xs:sequence> 
     <xs:any maxOccurs="2" minOccurs="0"/> 
     <xs:element name="node" type="xs:string"/> 
     <xs:any maxOccurs="2" minOccurs="0"/> 
    </xs:sequence> 
    </xs:complexType 

XSD не позволяет этого, в силу определенных причин.
Вышеупомянутый пример - всего лишь образец. Практический XML поставляется со сложной иерархией XML-тегов.

Просьба сообщить мне, можете ли вы его взломать.

Кстати, альтернативным решением является вставка XSL-преобразования перед процессом проверки. Ну, я избегаю этого, потому что мне нужно изменить код .Net, который инициирует процесс проверки, который поддерживается, по крайней мере, моей компанией.

+0

Проблема в том, что она не проверяет схему? –

+0

yup .. скорее я хотел показать, что «я не знаю, как это сделать .. и я попробовал ЭТО» .. –

ответ

2

Заключение:

Это невозможно с XSD. Все подходы, которые я пытался достичь, были названы «неоднозначными» с помощью инструментов проверки, сопровождающих множество ошибок.

1

Может быть, его можно использовать пространство имен:

<xs:element name="root" type="root"></xs:element> 
    <xs:complexType name="root"> 
    <xs:sequence> 
     <xs:any maxOccurs="2" minOccurs="0" namespace="http://ns1.com" /> 
     <xs:element name="node" type="xs:string"/> 
     <xs:any maxOccurs="2" minOccurs="0" namespace="http://ns2.com"/> 
    </xs:sequence> 
    </xs:complexType> 

Это, вероятно, проверить.

+0

хорошо подумал [+1] .. но, к сожалению, не работает в моем случае. thanx для ответа. :-) –

3

В случае вы не сделали с этим, вы можете попробовать следующее:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
    <xs:element name="root" type="root"></xs:element> 
    <xs:complexType name="root"> 
    <xs:sequence> 
     <xs:any maxOccurs="2" minOccurs="0" processContents="skip"/> 
     <xs:element name="node" type="xs:string"/> 
     <xs:any maxOccurs="2" minOccurs="0" processContents="skip"/> 
    </xs:sequence> 
    </xs:complexType> 
</xs:schema> 

В Linux это работает отлично с xmllint использованием Libxml версии 20706.

+0

однако он все еще не позволяет первому элементу быть ЛЮБОЙ! :( –

+1

В чем же проблема, пожалуйста? – alk

+0

это ошибка, которую я получаю: ** Подстановочный знак ## any 'позволяет элементу' node ', и вызывает модель содержимого, которая становится неоднозначной. Так и так ** –

1

я столкнулся с той же проблемой.

Поскольку я вызывал проверку с .NET; Я решил подавить конкретную ошибку проверки в ValidationEventHandler в качестве обходного пути. Это сработало для меня.

private void ValidationEventHandler(object sender, ValidationEventArgs e) 
    { 
     switch (e.Severity) 
     { 
      case XmlSeverityType.Warning: 
       // Processing warnings 
       break; 
      case XmlSeverityType.Error: 
       if (IgnoreUnknownTags 
        && e.Exception is XmlSchemaValidationException 
        && new Regex(
         @"The element '.*' has invalid child element '.*'\." 
         + @" List of possible elements expected:'.*'\.") 
         .IsMatch(e.Exception.Message)) 
       { 
        return; 
       } 
       // Processing errors 
       break; 
      default: 
       throw new InvalidEnumArgumentException("Severity should be one of the valid values"); 
     } 
    } 

Важно, что Thread.CurrentUICulture должен быть установлен на английский или CultureInfo.InvariantCulture для текущего потока для этого, чтобы работать.

0

Вы можете использовать новую функцию в XML 1.1 под названием «Open Content». Короче говоря, вы можете указать, что дополнительные «неизвестные» элементы могут быть добавлены к сложному типу в разных положениях и что должен делать парсер, если он попадает в любой из этих элементов.

Использование XML 1.1, ваш сложный тип стал бы:

<xs:element name="root" type="root" /> 
<xs:complexType name="root"> 
    <xs:openContent mode="interleave"> 
    <xs:any namespace="##any" processContents="skip"/> 
    </xs:openContent> 

    <xs:sequence> 
    <xs:element name="node" type="xs:string"/> 
    </xs:sequence> 
</xs:complexType> 

Если у вас есть много сложных типов, вы можете также установить режим открытого контента «по умолчанию» в верхней части схемы:

<xs:schema ...> 
    <xs:defaultOpenContent mode="interleave"> 
    <xs:any namespace="##any" processContents="skip"/> 
    </xs:defaultOpenContent> 

    ... 
</xs:schema> 

Специфика W3C для открытого контента можно найти по адресу http://www.w3.org/TR/xmlschema11-1/#oc, и есть хорошая запись об этом на http://www.ibm.com/developerworks/library/x-xml11pt3/#N102BA.

К сожалению, .NET не поддерживает XML 1.1, как еще я не могу найти 1,1 процессоров бесплатно XML - но пару платных опций:

Смежные вопросы