Ошибка при проверке XML в xsi: значение типа - PullRequest
0 голосов
/ 27 февраля 2019

У меня есть этот XML, который я использовал в HTTP-запросе

<?xml version="1.0"?>
<updateList xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:m="urn:messages_namespace" xmlns:listRel="urn:relationships_namespace" xmlns:pc="urn:core_namespace">
  <pc:record xsi:type="listRel:Customer" internalId="46" xmlns:listRel="urn:relationships_namespace">
    <listRel:companyName>T Tax</listRel:companyName>
  </pc:record>
  <pc:record xsi:type="listRel:Customer" internalId="44" xmlns:listRel="urn:relationships_namespace">
    <listRel:companyName>S Tax</listRel:companyName>
  </pc:record>
  <pc:record xsi:type="listRel:Customer" internalId="45" xmlns:listRel="urn:relationships_namespace">
    <listRel:companyName>K Tax</listRel:companyName>
  </pc:record>
</updateList>

, и XSD, который я сгенерировал для этого XML, выглядит примерно так:

<xs:element name="updateList">
<xs:complexType>
  <xs:sequence>
    <xs:element maxOccurs="unbounded" name="record">
      <xs:complexType>
        <xs:sequence>
          <xs:element name="companyName" type="xs:string" />
        </xs:sequence>
        <xs:attribute name="internalId" type="xs:unsignedByte" use="required" />
      </xs:complexType>
    </xs:element>
  </xs:sequence>
</xs:complexType>

Но когда я пытаюсь проверить тот же XML по сгенерированной схеме, я получаю эту ошибку -

    This is an invalid xsi:type 'urn:relationships_namespace:Customer'.

для всех трех записей о клиентах в XML.Но запутанная часть заключается в том, что HTTP-запрос работает нормально без каких-либо изменений.Буду признателен за любую помощь в этом.Застрял так долго.

PS - также проверил различные ответы StackOverFlow, но до сих пор ни один из них не работал.

1 Ответ

0 голосов
/ 28 февраля 2019

XSD не так.В XSD с targetNamespace urn:core_namespace вы должны определить именованный тип для ваших элементов записи, например, Record:

Давайте назовем этот файл схемы core.xsd для дальнейшего использования:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- EDIT 2019-03-17: added missing xmlns -->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="urn:core_namespace" targetNamespace="urn:core_namespace" elementFormDefault="qualified">
  <xs:complexType name="Record">
        <!-- EDIT 2019-03-17: moved 'companyName' element to Customer type in relationships.xsd -->
        <xs:attribute name="internalId" type="xs:unsignedByte" use="required" />
  </xs:complexType>
  <!-- EDIT 2019-02-28: ADDED 'record' element-->
  <xs:element name="record" type="Record" />
</xs:schema>

В другом XSD с targetNamespcae urn:relationships_namespace необходимо импортировать предыдущий XSD и определить тип Customer как расширение типа записи:

Давайте назовем этофайл схемы relationships.xsd для последующего использования:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"  targetNamespace="urn:relationships_namespace" 
xmlns:pc="urn:core_namespace" elementFormDefault="qualified">
  <xs:import namespace="urn:core_namespace" schemaLocation="core.xsd"/>
  <xs:complexType name="Customer">
    <xs:complexContent>
      <xs:extension base="pc:Record">
        <!-- EDIT 2019-03-17: added 'companyName' element (moved from Record type in core.xsd) -->
        <xs:sequence>
          <xs:element name="companyName" type="xs:string" />
        </xs:sequence>
      </xs:extension>
    </xs:complexContent>
  </xs:complexType>
</xs:schema>

- РЕДАКТИРОВАТЬ 2019-02-28: добавлена ​​схема ниже -

и окончательный вариантсхема, определяющая ваш updateList элемент.

Давайте назовем этот файл схемы messages.xsd для дальнейшего использования:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"  targetNamespace="urn:messages_namespace" 
xmlns:pc="urn:core_namespace" elementFormDefault="qualified">
  <xs:import namespace="urn:core_namespace" schemaLocation="core.xsd"/>
  <xs:element name="updateList">
    <xs:complexType>
      <xs:sequence>
        <xs:element ref="pc:record" maxOccurs="unbounded" />
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

Для schemaLocation с,при этом предполагается, что все XSD находятся в одной папке, в противном случае измените схемы расположения соответственно.

РЕДАКТИРОВАТЬ 2019-03-17

Кроме того, пожалуйста, исправьте свой XMLчтобы убедиться, что элемент updateList находится в urn:messages_namespace: замените xmlns:m="urn:messages_namespace" на xmlns="urn:messages_namespace" (пространство имен по умолчанию).

Итак, вот фиксированный XML, скажем, он находится в файле updateList.xml:

<?xml version="1.0"?>
<updateList xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:messages_namespace" xmlns:listRel="urn:relationships_namespace" xmlns:pc="urn:core_namespace">
  <pc:record xsi:type="listRel:Customer" internalId="46" xmlns:listRel="urn:relationships_namespace">
    <listRel:companyName>T Tax</listRel:companyName>
  </pc:record>
  <pc:record xsi:type="listRel:Customer" internalId="44" xmlns:listRel="urn:relationships_namespace">
    <listRel:companyName>S Tax</listRel:companyName>
  </pc:record>
  <pc:record xsi:type="listRel:Customer" internalId="45" xmlns:listRel="urn:relationships_namespace">
    <listRel:companyName>K Tax</listRel:companyName>
  </pc:record>
</updateList>

Вот пример кода Java и пояснение того, как проверять XML с помощью файлов схемы XML (работает для меня с Java 8 ивсе XSD и XML-файлы в рабочем каталоге, поместите это в метод main класса, если вы хотите его протестировать):

// XSD compiler
final SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
// Load all XSD files starting with core.xsd
final Source coreXsd = new StreamSource(new File("core.xsd"));
final Source relationshipsXsd = new StreamSource(new File("relationships.xsd"));
final Source messagesXsd = new StreamSource(new File("messages.xsd"));
final Source[] schemaSources = { coreXsd, relationshipsXsd, messagesXsd };
// Compile the final schema for validation
final Schema schema = schemaFactory.newSchema(schemaSources);
// XML to be validated
final Source xml = new StreamSource(new File("updateList.xml"));
// Validate
final Validator validator = schema.newValidator();
validator.validate(xml);
System.out.println(xml.getSystemId() + " is valid.");
...