Как игнорировать проверку неизвестных тегов?

StackOverflow https://stackoverflow.com/questions/2402452

  •  18-09-2019
  •  | 
  •  

Вопрос

Еще одна проблема с возможностями 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, который запускает процесс проверки, который, по крайней мере, поддерживается моей компанией.

Это было полезно?

Решение 2

Заключение:

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

Другие советы

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

<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.

Возможно, можно использовать пространства имен:

<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>

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

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

Поскольку я вызвал проверку из .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 для текущего потока, чтобы это работало.

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

Используя 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. Я не могу найти бесплатных процессоров XML 1.1, но есть несколько платных опций:

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top