Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Cannot read XSD attribute with QXMLStreamReader
Forum Updated to NodeBB v4.3 + New Features

Cannot read XSD attribute with QXMLStreamReader

Scheduled Pinned Locked Moved Unsolved General and Desktop
qxmlstreamreadexmlxsdparsing
4 Posts 2 Posters 925 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • J Offline
    J Offline
    jepessen
    wrote on 18 May 2020, 20:16 last edited by
    #1

    I need to parse the following XSD:

    <?xml version="1.0" encoding="UTF-8"?>
    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
      <xs:element name = "elementName">
        <xs:simpleType>
          <xs:restriction base = "xs:string">
          </xs:restriction>
        </xs:simpleType>
      </xs:element>
    </xs:schema>
    

    During the parsing I arrive to the restriction element. This is the code (rearranged) for parsing this element, that uses QXMLStreamReader

    void String::getFromBase() const {
      QXMLStreamReader m_node; // in true code it's a class member already initialized
      m_node.readNextStartElement();
      auto name = stripNamespace(m_node.name().toString()); // convert xs:restriction to restriction
      if (name != restriction) {
        throw Exception("Restriction is not found when reading string data");
      }
      bool hasBase{false};
      auto x = m_node.attributes().size(); // x is zero but it should be one
      for (const auto& it : m_node.attributes()) {
        auto attrName = stripNamespace(it.name().toString());
        if (attrName == "base") {
          hasBase = true;
          break;
        }
      }
      if (!hasBase) {
        throw Exception("Restriction needs 'base' attribute");
      }
      auto attribute = stripNamespace(m_node.attributes().value(BaseLabel).toString());
      if (attribute == "string") {
        int i = 0;
      }
    }
    

    When I run the code, the variable name is "restriction", so I arrive to the right position in the XML. But then when I retrieve attributes with attributes() the list is empty (in the code x is equal to zero) do I don't enter in the loop for cycling all attributes.

    What I'm doing wrong and what should I do for retrieving attributes of the node?

    V 1 Reply Last reply 18 May 2020, 22:12
    0
    • J jepessen
      18 May 2020, 20:16

      I need to parse the following XSD:

      <?xml version="1.0" encoding="UTF-8"?>
      <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
        <xs:element name = "elementName">
          <xs:simpleType>
            <xs:restriction base = "xs:string">
            </xs:restriction>
          </xs:simpleType>
        </xs:element>
      </xs:schema>
      

      During the parsing I arrive to the restriction element. This is the code (rearranged) for parsing this element, that uses QXMLStreamReader

      void String::getFromBase() const {
        QXMLStreamReader m_node; // in true code it's a class member already initialized
        m_node.readNextStartElement();
        auto name = stripNamespace(m_node.name().toString()); // convert xs:restriction to restriction
        if (name != restriction) {
          throw Exception("Restriction is not found when reading string data");
        }
        bool hasBase{false};
        auto x = m_node.attributes().size(); // x is zero but it should be one
        for (const auto& it : m_node.attributes()) {
          auto attrName = stripNamespace(it.name().toString());
          if (attrName == "base") {
            hasBase = true;
            break;
          }
        }
        if (!hasBase) {
          throw Exception("Restriction needs 'base' attribute");
        }
        auto attribute = stripNamespace(m_node.attributes().value(BaseLabel).toString());
        if (attribute == "string") {
          int i = 0;
        }
      }
      

      When I run the code, the variable name is "restriction", so I arrive to the right position in the XML. But then when I retrieve attributes with attributes() the list is empty (in the code x is equal to zero) do I don't enter in the loop for cycling all attributes.

      What I'm doing wrong and what should I do for retrieving attributes of the node?

      V Offline
      V Offline
      VRonin
      wrote on 18 May 2020, 22:12 last edited by
      #2

      @jepessen said in Cannot read XSD attribute with QXMLStreamReader:

      (rearranged)

      I think this is the key. To be able to read the attributes m_node.isStartElement() must return true just before calling m_node.attributes(). What I suspect is happening is that in the real code you are moving the cursor beyond the StartElement before calling m_node.attributes()

      "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
      ~Napoleon Bonaparte

      On a crusade to banish setIndexWidget() from the holy land of Qt

      J 1 Reply Last reply 19 May 2020, 07:17
      1
      • V VRonin
        18 May 2020, 22:12

        @jepessen said in Cannot read XSD attribute with QXMLStreamReader:

        (rearranged)

        I think this is the key. To be able to read the attributes m_node.isStartElement() must return true just before calling m_node.attributes(). What I suspect is happening is that in the real code you are moving the cursor beyond the StartElement before calling m_node.attributes()

        J Offline
        J Offline
        jepessen
        wrote on 19 May 2020, 07:17 last edited by
        #3

        @VRonin this is almost the real code I don't call readNextStartElement or readNextElement anywhere else in the function, so I' trying to retrieve attributes when m_node.name() is "restriction".

        This is the actual real code (A bit incomplete because I'm focusin on this issue):

        Tree::String::Ptr String::getFromBase() const {
          auto parsedNode = make_shared<Tree::String>();
          m_node.readNextStartElement();
          auto name = stripNamespace(m_node.name().toString());
          if (name != RestrictionLabel) {
            throw Exception("Restriction is not found when reading string data");
          }
          auto x = m_node.attributes().size();
          bool hasBase{ false };
          for (const auto& it : m_node.attributes()) {
            auto attrName = stripNamespace(it.name().toString());
            if (attrName == BaseLabel) {
              hasBase = true;
              break;
            }
          }
          if (!hasBase) {
            throw Exception("Restriction needs 'base' attribute");
          }
          auto attribute = stripNamespace(m_node.attributes().value(BaseLabel).toString());
          if (attribute == StringLabel) {
            int i = 0;
          }
          return parsedNode;
        }
        
        1 Reply Last reply
        0
        • V Offline
          V Offline
          VRonin
          wrote on 19 May 2020, 09:14 last edited by VRonin
          #4

          I'm sorry but you must be moving the cursor in some way. Try putting Q_ASSERT(m_node.isStartElement()); just before auto x = m_node.attributes().size();

          This example parses the XSD you provided correctly (I also let QXmlStreamReader handle namespaces instead of having to write custom code for it):

          int main()
          {
              const QString xmlText(R"***(<?xml version="1.0" encoding="UTF-8"?>
              <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
                <xs:element name = "elementName">
                  <xs:simpleType>
                    <xs:restriction base = "xs:string">
                    </xs:restriction>
                  </xs:simpleType>
                </xs:element>
              </xs:schema>)***"
              );
              QXmlStreamReader reader(xmlText);
              while (!reader.atEnd()) {
                  switch(reader.readNext()){
                  case QXmlStreamReader::StartDocument:
                      qDebug("Start of document");
                      break;
                  case QXmlStreamReader::EndDocument:
                      qDebug("End of document");
                      break;
                  case QXmlStreamReader::StartElement:{
                      qDebug() << "Started Element: " << reader.name();
                      const auto attr = reader.attributes();
                      qDebug() << "Number of Attributes: " << attr.size() << " Attributes:";
                      for(auto&& att : attr)
                          qDebug() << att.name() << " = " << att.value();
                  }
                      break;
                  case QXmlStreamReader::EndElement:
                      qDebug() << "Finished Element: " << reader.name();
                      break;
                  default:
                      break;
                  }
              }
              return 0;
          }
          

          "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
          ~Napoleon Bonaparte

          On a crusade to banish setIndexWidget() from the holy land of Qt

          1 Reply Last reply
          1

          2/4

          18 May 2020, 22:12

          • Login

          • Login or register to search.
          2 out of 4
          • First post
            2/4
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • Users
          • Groups
          • Search
          • Get Qt Extensions
          • Unsolved