9

FictionBook (also known as FB2) is an XML-based format of electronic books. Its schema can be found here:

http://gribuser.ru/xml/fictionbook/2.0/xsd/

However, when I downloaded this schema and tried to open it in Visual Studio 2012 I got a bunch of errors, the first of which was: Prefix '' cannot be mapped to namespace name reserved for "xml" or "xmlns". Line 5, position 118. E:\dev\fb2\FictionBook2.xsd.

Is the schema really invalid? If so, how is it possible that a lot of software use it to validate FB2 files? Is there an easy way to modify the schema to make VS happy?

thorn0
  • 9,362
  • 3
  • 68
  • 96
  • The problem's actually with http://gribuser.ru/xml/fictionbook/2.0/xsd/FictionBookLang.xsd . You'll see a problem just trying to display it in a browser. – Mark Hurd May 18 '13 at 21:55
  • And FYI I found this by trying to replicate your issue using the .NET Framework classes. `Xml.Schema.XmlSchema.Read(XmlReader.Create("http://gribuser.ru/xml/fictionbook/2.0/xsd/FictionBookLang.xsd"),Nothing)` reproduces the error. – Mark Hurd May 18 '13 at 22:06
  • I understand that it's because of FictionBookLang.xsd, but still can't figure out how to fix it. – thorn0 May 19 '13 at 10:22
  • Yeah, if I knew that I would have answered rather than just commented :-) – Mark Hurd May 19 '13 at 10:24

2 Answers2

5

The only thing you need to do is to remove xmlns="http://www.w3.org/XML/1998/namespace" from FictionBookLang.xsd, as that is the only culprit:

enter image description here

The author of the set most likely wanted to ensure that the xml:lang attribute is made available to people. It is not the right way, but nonetheless it could work in certain scenarios.

Typically this is done differently. If your XSD-aware XML processor is "smart", such an import should be done like so, i.e. instead of

<xs:import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="FictionBookLang.xsd"/>

it should be:

<xs:import namespace="http://www.w3.org/XML/1998/namespace"/>

This is called a dangling external reference; "smart" XSD processors know how to resolve locations to well known namespaces (for sure, http://www.w3.org/XML/1998/namespace is one of those).

This is what the set would look like, after using the dangling import; the xml.xsd was automatically added by the processor, and it should a copy of the one listed here.

enter image description here

In other words, normally FictionBookLand.xsd SHOULD NOT even be part of the compilation. Particularly, if you get these XSDs combined with others that reference the xml:lang attribute correctly, then you will get a duplicate attribute declaration error.

Anyway, if you remove just the attribute as described, all becomes valid; from there, you could build a sample XML - the XSDs are otherwise fine. The sample I've got generated is huge, I am posting just the first couple of lines...

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<!-- Sample XML generated by QTAssistant (http://www.paschidev.com) -->
<FictionBook xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:genre="http://www.gribuser.ru/xml/fictionbook/2.0/genres" xmlns="http://www.gribuser.ru/xml/fictionbook/2.0">
    <stylesheet type="type1">stylesheet1</stylesheet>
    <description>
        <title-info>
            <genre match="100">architecture</genre>
            <author>
                <first-name xml:lang="en">first-name1</first-name>
                <middle-name xml:lang="en">middle-name1</middle-name>
                <last-name xml:lang="en">last-name1</last-name>
                <nickname xml:lang="en">nickname1</nickname>
                <home-page>home-page1</home-page>
                <home-page>home-page1</home-page>
                <email>email1</email>
                <email>email1</email>
            </author>
            <book-title xml:lang="en">book-title1</book-title>
            <annotation id="ID1" xml:lang="en">
Petru Gardea
  • 21,373
  • 2
  • 50
  • 62
2

I think the issue might be with the targetNamespace=http://www.gribuser.ru/xml/fictionbook/2.0" and xmlns="http://www.gribuser.ru/xml/fictionbook/2.0" attributes in the opening tag. Running xmllint --schema FictionBook2.xsd --auto gives the following error:

FictionBookLang.xsd:3: namespace error : xml namespace URI cannot be the default namespace
="http://www.w3.org/2001/XMLSchema" xmlns="http://www.w3.org/XML/1998/namespace"

Removing those attributes got rid of these errors, although I wasn't able to fully coerce xmllint into successfully generating a sample XML file.

Jesse Sweetland
  • 1,594
  • 11
  • 10