Расширить существующую схему XSD с помощью пользовательского атрибута - PullRequest
0 голосов
/ 14 мая 2019

Мне нужно добавить пользовательский атрибут в XML-файл, который проверяется существующей, уже определенной схемой.

Учитывая существующий элемент xml:

<existingElement attr1="1" attr2="2" />

Проверено с существующей схемой xsd, я хочу сделать возможным добавление пользовательского атрибута к этому элементу без нарушения проверки схемы в процессе:

<existingElement attr1="1" attr2="2" xmlns:my="http://example.com/node" my:id="myNodeId" />

Я не могу изменить исходный файл схемы, и в нем есть элемент anyAttribute

Какой подход мне выбрать?

Я пытался добавить еще один xsd-файл:

<xs:schema 
    targetNamespace="http://example.com/node"
    attributeFormDefault="qualified"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
>
  <xs:attribute name="id" type="xs:string" />
</xs:schema>

Но я продолжаю получать Attribute 'http://example.com/node:id' was not declared.

Я проверяю в .NET, используя XmlSchemaSet с добавлением как старых, так и новых схем.

Ответы [ 2 ]

1 голос
/ 14 мая 2019

На некотором уровне вы ДОЛЖНЫ изменить существующую схему, потому что вы пытаетесь создать экземпляр документа, который нарушает одно из его ограничений.

Если исходная схема определяет структуру с использованием именованного сложного типа, то вы можете изменить существующую схему без текстового изменения текста документа схемы, используя один из двух механизмов: xs:redefines или определив новый сложный тип, используя «вывод по расширению». Оба из них изменяют схему без изменения документа схемы: так что это немного зависит от того, что вы подразумеваете под вашим требованием не изменять схему. Обратите внимание, что если вы используете «деривацию по расширению», то ваш экземпляр должен будет указать, что он использует расширение, включив атрибут xsi:type, который называет расширенный сложный тип.

Если ваша забота об изменении схемы связана с разветвлением определения источника XSD, тогда другой способ определить вашу измененную схему - это преобразование XSLT, примененное к оригиналу. На самом деле это очень похоже на xs: redefines, за исключением того, что вы можете вносить любые изменения, которые вам нравятся, тогда как xs: redefined ограничивает то, что вы можете изменить.

С другой стороны, если вы заботитесь о том, чтобы документы, соответствующие новой схеме, по-прежнему были совместимы с приложениями, использующими старую схему, то все эти механизмы не работают: во всех случаях вы создаете документы, которые не соответствуют к существующей схеме, что может привести к поломке приложений, которые полагаются на документы, действительные по этой схеме.

0 голосов
/ 14 мая 2019

test.xml

<?xml version="1.0" encoding="utf-8"?>
<existingElement attr1="1" attr2="2" xmlns:my="http://example.com/node" my:id="myNodeId" />

test1.xsd

<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

  <xs:element name="existingElement">
    <xs:complexType>
      <xs:attribute name="attr1" type="xs:unsignedByte" use="required" />
      <xs:attribute name="attr2" type="xs:unsignedByte" use="required" />
      <xs:anyAttribute />
    </xs:complexType>
  </xs:element>
</xs:schema>

test2.xsd

<?xml version="1.0" encoding="utf-8"?>
<xs:schema targetNamespace="http://example.com/node"
           xmlns:xs="http://www.w3.org/2001/XMLSchema">

  <xs:attribute name="id" type="xs:string" />
</xs:schema>

Код C #

var schemaSet = new XmlSchemaSet();
schemaSet.Add("", "test1.xsd");
schemaSet.Add("http://example.com/node", "test2.xsd");
schemaSet.Compile();

var xml = XDocument.Load("test.xml");
xml.Validate(schemaSet, (o, e) =>
{
    Console.WriteLine(e.Severity + ": " + e.Message);
});

Оно работает.Нет ошибок проверки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...