2015-03-25 3 views
2

У меня есть несколько файлов схемы Xsd (маленькие) и хотелось бы каким-то образом объединить их в один большой файл, я думал о файле xml с 1 узлом для каждого содержимого схемы Xsd, в C# кода, выбирая соответствующий раздел и проверяя его. Проблема заключается в том, что я вижу предупреждение «Глобальный элемент« xxx »уже был объявлен». При открытии Xml-файла с помощью Visual studio (я определенно не эксперт Xsd, я действительно повторяю тот же самый элемент).Несколько схем Xsd в 1 файле

Любые идеи о правильности этого подхода? Должен ли я использовать CData для содержимого Xsd, может быть?

Примеры файлов XML:

Xml 1:

<resource xmlns=""> 
    <identifier>5401902302111</identifier> 
    <product>printer</product> 
    <requestedby /> 
</resource> 

Xml 2:

<resource xmlns=""> 
    <identifier>5401902302112</identifier> 
    <email>[email protected]</email> 
</resource> 

XSD 1:

<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
      <xs:element name="resource"> 
       <xs:complexType> 
       <xs:sequence> 
        <xs:element type="xs:long" name="identifier"/> 
        <xs:element type="xs:string" name="requestedby"/> 
        <xs:element type="xs:string" name="product"/> 
       </xs:sequence> 
       </xs:complexType> 
      </xs:element> 
      </xs:schema> 

XSD 2:

<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
      <xs:element name="resource"> 
       <xs:complexType> 
       <xs:sequence> 
        <xs:element type="xs:long" name="identifier"/> 
        <xs:element type="xs:string" name="email"/> 
       </xs:sequence> 
       </xs:complexType> 
      </xs:element> 
      </xs:schema> 

То, что я хочу, чтобы в конце концов:

*<?xml version="1.0" encoding="utf-8"?> 
<resource> 
    <resourcedata type="acquisition"> 
    <details> 
     <xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
     <xs:element name="resource"> 
      <xs:complexType> 
      <xs:sequence> 
       <xs:element type="xs:long" name="identifier"/> 
       <xs:element type="xs:string" name="requestedby"/> 
       <xs:element type="xs:string" name="product"/> 
      </xs:sequence> 
      </xs:complexType> 
     </xs:element> 
     </xs:schema> 
    </details> 
    </resourcedata> 
    <resourcedata type="warningletter"> 
    <details> 
     <xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
     <xs:element name="resource"> 
      <xs:complexType> 
      <xs:sequence> 
       <xs:element type="xs:long" name="identifier"/> 
       <xs:element type="xs:string" name="email"/> 
      </xs:sequence> 
      </xs:complexType> 
     </xs:element> 
     </xs:schema> 
    </details> 
    </resourcedata> 
</data>* 

C# код:

var xsdContent = 
       xDoc.Element("resource").Elements("resourcedata") 
        .Where(
         x =>        
          x.Attribute("type").Value == "acquisition") 
        .FirstOrDefault().Element("details").FirstNode.ToString();    


      var doc = new XDocument(xElementContent); 

      XmlSchemaSet schemas = new XmlSchemaSet(); 
      schemas.Add("", XmlReader.Create(new StringReader(xsdContent))); 

      Console.WriteLine("Validating doc"); 
      bool errors = false; 
      doc.Validate(schemas, (o, e) => 
      { 
       Console.WriteLine("{0}", e.Message); 
       Console.WriteLine("{0}", e.Exception); 
       errors = true; 
      }); 

      Console.WriteLine("doc {0}", errors ? "did not validate" : "validated"); 

(xElementContent переменная содержит контент Xml)

Благодаря

+0

Почему у вас есть несколько документов XSD, если они маленькие? Почему у вас нет единого документа схемы? Что вы подразумеваете под повторением элемента? Пожалуйста, покажите любой соответствующий код C# и минимальный образец всех файлов схемы и XML-документ, подлежащий проверке. –

+0

Вы только показываете _one_ XSD документ - все остальные не являются файлами схемы. Полностью неясно, о чем вы спрашиваете. –

+0

Я согласен с Матиасом. Это интересный подход, который, однако, может быть мотивирован больше недоразумением, чем конкретные требования, требующие отклонения от стандартных методов проверки. Если у вас нет конкретных, убедительных причин для перехода по этому пути, я предлагаю вам делать вещи [более условно] (http://stackoverflow.com/a/29261615/290085). – kjhughes

ответ

1

Вместо того, чтобы изобретать йо ur собственный, ad-hoc способ объединить XSD, вы должны использовать стандартные методы на основе xsd:include или xsd:import.

См. Также: What's the difference between xsd:include and xsd:import?

И если у вас нет особых причин для отправки вашей проверки с использованием специальных методов в коде, вы должны подтвердить ее на уровне документа и позволить парсеру выполнить поиск соответствующих объявлений для вас.

+0

Я понимаю, что это «отклонение от стандартных методов проверки» - я отредактировал вопрос соответствующим образом. Я просто хотел попробовать как-то избавиться от наличия> 20 Xsd-файлов - у меня может быть около 20 типов Xml в качестве действительных запросов, и для каждого мне нужен отдельный файл Xsd. Я думаю, что я могу пойти с альтернативой содержанию Xsd в раздел CData. – aly

+2

Тем не менее, «устранение как-то накладных расходов на наличие> 20 файлов Xsd» на самом деле не оправдывает такой неортодоксальный подход. (Я видел, как клиенты используют сотни XSD, работающих плавно вместе.) Кроме того, необходимость прибегать к CDATA должна сигнализировать вам, что вы плаваете вверх по течению. Либо вы не мотивируете свои дизайнерские решения здесь, либо вы делаете это сложнее, чем должно быть. Все показания пока указывают на последнее. Не пытайтесь критиковать, но иногда лучшая помощь должна предлагать изменение направления. – kjhughes

+0

Главный вопрос: если это возможно \ технически правильно (я говорю, что я не эксперт Xsd), и из ваших ответов я вижу, что в принципе нет, так что спасибо за ответы. К сожалению, что я сказал до сих пор, это вся информация, которую я могу предоставить с дизайнерской точки зрения. – aly

2

В отличие от других, я думаю, что единственная проблема с вашим вопросом заключается в том, что она не позволяет проиллюстрировать хороший пример того, почему можно создать формат XML-файла, как описано вами. На самом деле, я был вовлечен в интересной дискуссии here on SO, для которых CM Sperberg-Маккуин даже сколотить demo, заключая:

Таким образом, показано, что множество документов схемы спецификации-совместимой могут быть встроены в том же XML документ. (Так как это, как представляется, проблемой для некоторых заинтересованных сторон, следует, по-видимому, также следует отметить, что WSDL не участвует здесь.)

я был вынужден связать С. М.Ответ Sperberg-McQueen, так как вы сказали Я думал о файле xml, а не о файле XSD (который был бы точкой kjhughes).

Почему я думаю, что у вас не было хорошего сценария, потому что следующая единственная схема очень хорошо удовлетворит ваши XML.

<?xml version="1.0" encoding="utf-8"?> 
<!--XML Schema generated by QTAssistant/XML Schema Refactoring (XSR) Module (http://www.paschidev.com)--> 
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
    <xs:element name="resource"> 
     <xs:complexType> 
      <xs:sequence> 
       <xs:element name="identifier" type="xs:unsignedLong"/> 
       <xs:choice> 
        <xs:element minOccurs="0" name="email" type="xs:string"/> 
        <xs:sequence> 
         <xs:element minOccurs="0" name="product" type="xs:string"/> 
         <xs:element minOccurs="0" name="requestedby" type="xs:string"/>        
        </xs:sequence> 
       </xs:choice> 
      </xs:sequence> 
     </xs:complexType> 
    </xs:element> 
</xs:schema> 

Давайте рассмотрим некоторые сценарии (пожалуйста, обновите ваш вопрос, если у вас есть что-то еще):

  • Корневой элемент может иметь другое имя. В этом случае просто создайте еще один глобальный элемент, соответствующий этому имени.
  • Ваш корневой элемент может находиться в другом пространстве имен. В этом случае просто создайте еще один XSD-файл с целевым пространством имен, соответствующим пространству имен XML. Затем добавьте все свои XSD в XmlSchemaSet и проведите проверку.
  • Для одного и того же элемента ваши модели контента могут быть разными, но совместимыми с точки зрения того, что XSD 1.0 (так как вы показываете фондовый код .NET, я предполагаю, что вы застряли в поддержке .NET). Это будет в случае с схемой, которую я создал выше.
  • Вы не можете использовать XSD 1.0; он может или не работать с функциями в XSD 1.1 (например, с ограничениями, типами альтернатив и т. д.) - точка в том, что XSD 1.1 здесь не применим. Тогда ваше предложение собрать несколько XSD в одном файле XML будет работать как шарм. Фактически, я бы назвал это альтернативой бедного человека для XSD 1.1 в мире .NET ...

Для последнего я бы рекомендовал несколько иной подход. Я бы использовал XInclude, чтобы связать XSD в одном файле - если это то, что требует ваша модель обработки; есть библиотека NET here. Это позволит авторизовать XSD самостоятельно, тем самым гарантируя, что каждый из них действителен, и используя общие редакторы (включая вашу Visual Studio).

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