我正在尝试使用QXmlSchema加载以下XML模式,但是QXmlSchema::load(const QUrl & source)始终返回false。有什么办法让Qt提供一些有关实际出了什么问题的信息?据我所知,该模式在多个验证器中都进行了很好的检查(w3c提供了一个看起来像通过的神秘输出)。

<?xml version="1.0" ?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">

<xsd:element name="message">
<xsd:complexType>
  <xsd:choice>

    <xsd:element name="login-reply">
      <xsd:simpleType>
        <xsd:restriction base="xsd:string">
          <xsd:enumeration value="Accepted" />
          <xsd:enumeration value="Rejected" />
        </xsd:restriction>
      </xsd:simpleType>
    </xsd:element>

    <xsd:element name="login-request" >
      <xsd:complexType>
        <xsd:sequence>
          <xsd:element name="username" type="xsd:string" nillable="false"/>
          <xsd:element name="password" type="xsd:string" nillable="false"/>
        </xsd:sequence>
      </xsd:complexType>
    </xsd:element>

    <xsd:element name="logout-request">
      <xsd:complexType>
        <xsd:sequence>
          <xsd:element name="username" type="xsd:string" nillable="false"/>
        </xsd:sequence>
      </xsd:complexType>
    </xsd:element>

    <xsd:element name="logout-reply">
      <xsd:simpleType>
        <xsd:restriction base="xsd:string">
          <xsd:enumeration value="Accepted" />
          <xsd:enumeration value="Rejected" />
        </xsd:restriction>
      </xsd:simpleType>
    </xsd:element>

    <xsd:element name="tasklist-request" />

    <xsd:element name="tasklist-reply">
      <xsd:complexType>
        <xsd:sequence minOccurs="1">
          <xsd:element name="package" minOccurs="1" nillable="false">
            <xsd:complexType>
              <xsd:sequence>
                <xsd:element name="taskgroup" minOccurs="1" nillable="false">
                  <xsd:complexType>
                    <xsd:sequence>
                      <xsd:element name="id" type="xsd:integer" minOccurs="1" />
                      <xsd:element name="task" type="xsd:string" minOccurs="1" />
                    </xsd:sequence>
                    <xsd:attribute name="id" type="xsd:integer" />
                    <xsd:attribute name="name" type="xsd:string" />
                  </xsd:complexType>
                </xsd:element>
              </xsd:sequence>
              <xsd:attribute name="id" type="xsd:integer" />
              <xsd:attribute name="name" type="xsd:string" />
            </xsd:complexType>
          </xsd:element>
        </xsd:sequence>
      </xsd:complexType>
    </xsd:element>

    <xsd:element name="starttask-request">
      <xsd:complexType>
        <xsd:sequence>
          <xsd:element name="task-id" />
        </xsd:sequence>
      </xsd:complexType>
    </xsd:element>

    <xsd:element name="starttask-reply">
      <xsd:simpleType>
        <xsd:restriction base="xsd:string">
          <xsd:enumeration value="Accepted" />
          <xsd:enumeration value="Rejected" />
        </xsd:restriction>
      </xsd:simpleType>
    </xsd:element>

  </xsd:choice>

</xsd:complexType>
</xsd:element>
</xsd:schema>

最佳答案

bool QXmlSchema::load()本身仅返回 bool(boolean) 型结果,该结果对于调试没有太大用处。但这是获得更好的错误消息的更好的方法。

您可以使用void QXmlSchema::setMessageHandler(QAbstractMessageHandler *handler)方法。

这是我的项目中的示例。

第一个子类 QAbstractMessageHandler

class MessageHandler : public QAbstractMessageHandler
{
public:
    MessageHandler()
      : QAbstractMessageHandler(),
        m_messageType(QtMsgType()),
        m_description(),
        m_sourceLocation(QSourceLocation())
    {}

    QString statusMessage() const
    {
        return m_description;
    }

    qint64  line() const
    {
        return m_sourceLocation.line();
    }

    qint64  column() const
    {
        return m_sourceLocation.column();
    }
protected:
    virtual void handleMessage(QtMsgType type,
                               const QString &description,
                               const QUrl &identifier,
                               const QSourceLocation &sourceLocation) Q_DECL_OVERRIDE
    {
        Q_UNUSED(type);
        Q_UNUSED(identifier);

        m_messageType = type;
        m_description = description;
        m_sourceLocation = sourceLocation;
    }
private:
    QtMsgType       m_messageType;
    QString         m_description;
    QSourceLocation m_sourceLocation;
};

然后在加载之前设置消息处理程序。
QFile file("myschema.xsd");
file.open(QIODevice::ReadOnly);

MessageHandler messageHandler;
QXmlSchema sch;
sch.setMessageHandler(&messageHandler);
if (sch.load(&file, QUrl::fromLocalFile(file.fileName()))==false)
{
    QString error = messageHandler.statusMessage();
    qint64 line = messageHandler.line();
    qint64 column = messageHandler.column();
    /*Do what need if error*/
}

关于c++ - 如何调试QXmlSchema的加载方法?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/15437610/

10-13 07:53