Я пишу библиотеку, которая принимает файлы xml и анализирует их. Чтобы пользователи не загружали недействительные xmls в мое приложение, я использую xerces для проверки файлов xml через xsd.

Однако мне удается проверить только xsd-файлы. Теоретически пользователь мог просто открыть этот файл и возиться с ним. Вот почему я хотел бы, чтобы мой xsd был жестко запрограммирован в моей библиотеке.

К сожалению, я пока не нашел способа сделать это с помощью XercesC ++.

Вот как это сейчас работает ...

bool XmlParser::validateXml(std::string a_XsdFilename)
{
    xercesc::XercesDOMParser  domParser;
    if (domParser.loadGrammar(a_XsdFilename.c_str(), xercesc::Grammar::SchemaGrammarType) == NULL)
    {
        throw Exceptions::Parser::XmlSchemaNotReadableException();
    }

    XercesParserErrorHandler parserErrorHandler;

    domParser.setErrorHandler(&parserErrorHandler);
    domParser.setValidationScheme(xercesc::XercesDOMParser::Val_Always);
    domParser.setDoNamespaces(true);
    domParser.setDoSchema(true);
    domParser.setValidationSchemaFullChecking(true);

    domParser.parse(m_Filename.c_str());

    return (domParser.getErrorCount() == 0);

}

std::string m_Filename - это переменная-член, содержащая путь к проверяемому xml.

std::string a_XsdFilename - это путь к xsd, по которому я проверяю.

XercesParserErrorHandler наследуется от xercesc::ErrorHandler и выполняет обработку ошибок.

Как я могу заменить std::string a_XsdFilename чем-то вроде std::string a_XsdText? Где std::string a_XsdText содержит само определение схемы вместо пути к файлу, содержащему определение схемы.

1
Detonar 11 Сен 2018 в 15:08

1 ответ

Лучший ответ

Я опишу три способа жесткого кодирования XSD в вашей программе:

  • загрузив XSD из пути к файлу (это то, что сейчас делает ваша примерная программа)
  • загрузив XSD из строки (это то, о чем вы просите)
  • путем загрузки XSD из предварительно скомпилированного двоичного файла

Загрузка XSD по пути к файлу

Борис Колпаков предлагает в записи блога < / a> эти приложения должны предоставлять файлы схемы XSD сами по себе, а не искать файлы схемы с помощью атрибутов xsi: schemaLocation или xsi: noNamespaceSchemaLocation , найденных в файле XML.

В сообщении блога есть ссылка на load -grammar-dom , пример программы (размещенной в открытом доступе), в которой используется xercesc :: DOMLSParser :: loadGrammar:

user@linux:~$ load-grammar-dom
usage: load-grammar-dom [test.xsd ... ] [test.xml ...]
user@linux:~$ 

Загрузка XSD из строки

Если вы хотите передать содержимое файла XSD в виде строки, вам нужно будет использовать другую перегрузку xercesc :: DOMLSParser :: load где вы проходите

const DOMLSInput *source

Вместо того

const char *const systemId

DOMLSInput можно создать с помощью xercesc :: MemBufInputSource и xercesc :: Wrapper4InputSource, как это

xercesc::Wrapper4InputSource source(
    new xercesc::MemBufInputSource(
       (const XMLByte *) (a_XsdText.c_str()),
    a_XsdText.size(),
    "A name");

(Отчасти адаптировано из https://stackoverflow.com/a/15829424/757777, но не проверено)

Загрузка XSD из предварительно скомпилированного двоичного файла

Включенный в программное обеспечение CodeSynthesis XSD встроенный пример (который размещен в открытом доступе) демонстрирует, как использовать

xercesc :: BinInputStream и xercesc :: XML dearsemarizePool

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

См. Также README.

Пример содержит программу xsdbin, которая компилирует файлы схемы XSD в двоичный файл.

user@linux:~$ xsdbin --help
Usage: xsdbin [options] <files>
Options:
  --help                 Print usage information and exit.
  --verbose              Print progress information.
  --output-dir <dir>     Write generated files to <dir>.
  --hxx-suffix <sfx>     Header file suffix instead of '-schema.hxx'.
  --cxx-suffix <sfx>     Source file suffix instead of '-schema.cxx'.
  --array-name <name>    Binary data array name.
  --disable-multi-import Disable multiple import support.
user@linux:~$

Схема XSD в makefile файл предварительно компилируется xsdbin, и результат оказывается внутри исполняемого файла примера.

1
Erik Sjölund 23 Сен 2018 в 08:42