[Newbie:]Determine DOMNode value datatype

Discussion in 'XML' started by Ralph Stuber, Apr 20, 2005.

  1. Ralph Stuber

    Ralph Stuber Guest

    Hello,

    I just started coding in c++, and I am currently working on a library to
    access stored data in xml format. I am using VC++6 and xerces-c-2.6.0. I
    parsed an xml document via a DOMBuilder*. If I take a DOMNode*, I am
    able to access its value by myNode->getFirstChild()->getNodeValue(). The
    parsed xml document contains an xml schema definition, which actually
    defines two types of elements under the root element:

    1) <nominal> with type <xs:string>
    2) <numerical> with type <xs:integer>

    The method myNode->getFirstChild()->getNodeType() always returns the
    value 3 which means that is is of type TEXT_NODE.

    My question: is it possible to determine the type of stored data in a
    DOMNode? I want to determine if it is a xs:string or an xs:integer. So I
    would be able to create char* results for string nodes (f.ex. company
    name), and integer results for integer nodes (f.ex. zipcode). Does the
    DOMBuilder parse the xml schema and does it transport the information
    provided by the scheme into the DOMNode*-pointer?

    Thanky in advance,

    greetings from Oldenburg, Germany

    Ralph

    P.S.: Code-Sniplets:

    Parsing:
    [...]
    static const XMLCh gLS[] = { chLatin_L, chLatin_S, chNull };
    DOMImplementation *impl =
    DOMImplementationRegistry::getDOMImplementation(gLS);
    DOMBuilder* parser = ((DOMImplementationLS*)impl)->
    createDOMBuilder(DOMImplementationLS::MODE_SYNCHRONOUS, 0);
    if (parser->canSetFeature(XMLUni::fgDOMValidation, true))
    parser->setFeature(XMLUni::fgDOMValidation, true);
    if (parser->canSetFeature(XMLUni::fgDOMNamespaces, true))
    parser->setFeature(XMLUni::fgDOMNamespaces, true);
    if (parser->canSetFeature(XMLUni::fgDOMDatatypeNormalization, true))
    parser->setFeature(XMLUni::fgDOMDatatypeNormalization, true);
    rootNode = parser->parseURI(xmlFile); // rootNode is a DOMNode*
    [...]
    Reading and trying to determine the value type...

    char* getValue(DOMNode* rootNode, char* elementName) {
    char* nodeValue = "";
    try{
    DOMNodeList* rootElementList = rootNode->getChildNodes();
    rootNode = rootElementList->item(0);
    DOMNodeList* subElementList = rootNode->getChildNodes();
    DOMNode* current = 0;
    for (unsigned int i=0; i<subElementList->getLength(); i++) {
    current = subElementList->item(i);
    if (current->getNodeType() == DOMNode::ELEMENT_NODE) {
    char* strValue = XMLString::transcode(current->getNodeName());
    if (XMLString::equals(strValue, elementName)) {
    nodeValue = XMLString::transcode(current->getFirstChild()->getNodeValue());
    cout << "Element-Wert:" << nodeValue << endl;
    cout << "Element-Typ:" << current->getFirstChild()->getNodeType() << endl;
    //*******************************************************************
    // it would be great here to determine the type of the
    // current->getFirstChild() value
    //*******************************************************************
    } else {
    }
    }
    }
    } catch (...) {
    }
    return nodeValue;
    }
    The xml document:
    <?xml version="1.0" encoding="ISO-8859-1" ?>
    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:noNamespaceSchemaLocation="carelis_config.xsd">
    <nominal>Test eines nominalen Wertes</nominal>
    <numerical>12221</numerical>
    </config>

    The xml schema:
    <?xml version="1.0" encoding="ISO-8859-1"?>
    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="config">
    <xs:complexType>
    <xs:sequence>
    <xs:element name="nominal" type="xs:string"/>
    <xs:element name="numerical" type="xs:integer"/>
    </xs:sequence>
    </xs:complexType>
    </xs:element>
    </xs:schema>
    --
    **** COMMODORE 64 BASIC V2 ****
    64K RAM SYSTEM 38911 BASIC BYTES FREE
    READY
    #
    Ralph Stuber, Apr 20, 2005
    #1
    1. Advertising

  2. Ralph Stuber

    ajm Guest

    Ralph,

    if i understood correctly it is the XML document (as opposed to the
    schema which asserts its validity) that you are parsing. as such
    there is not an obligation to even read the schema (though of course
    you are electing to use a validating parser in your case.)

    to my knowledge it is not possible to do what you want (if anyone has
    an idea in this direction I am certainly interested in hearing about it)
    and as a general rule when rolling your own parser you will have to
    build in document "intelligence" e.g., if element name = "numerical"
    then parse as int etc. working on the assumption that this is in fact
    true (i.e., that the document successfully validates)

    btw: if certain nodes of your document have a natural binding to objects
    in your code you might consider using operator<< and operator>> to handle
    XML aspects.

    hth
    ajm.


    Ralph Stuber <> wrote in message news:<d45ng9$v0b$>...
    > Hello,
    >
    > I just started coding in c++, and I am currently working on a library to
    > access stored data in xml format. I am using VC++6 and xerces-c-2.6.0. I
    > parsed an xml document via a DOMBuilder*. If I take a DOMNode*, I am
    > able to access its value by myNode->getFirstChild()->getNodeValue(). The
    > parsed xml document contains an xml schema definition, which actually
    > defines two types of elements under the root element:
    >
    > 1) <nominal> with type <xs:string>
    > 2) <numerical> with type <xs:integer>
    >
    > The method myNode->getFirstChild()->getNodeType() always returns the
    > value 3 which means that is is of type TEXT_NODE.
    >
    > My question: is it possible to determine the type of stored data in a
    > DOMNode? I want to determine if it is a xs:string or an xs:integer. So I
    > would be able to create char* results for string nodes (f.ex. company
    > name), and integer results for integer nodes (f.ex. zipcode). Does the
    > DOMBuilder parse the xml schema and does it transport the information
    > provided by the scheme into the DOMNode*-pointer?
    >
    > Thanky in advance,
    >
    > greetings from Oldenburg, Germany
    >
    > Ralph
    >
    > P.S.: Code-Sniplets:
    >
    > Parsing:
    > [...]
    > static const XMLCh gLS[] = { chLatin_L, chLatin_S, chNull };
    > DOMImplementation *impl =
    > DOMImplementationRegistry::getDOMImplementation(gLS);
    > DOMBuilder* parser = ((DOMImplementationLS*)impl)->
    > createDOMBuilder(DOMImplementationLS::MODE_SYNCHRONOUS, 0);
    > if (parser->canSetFeature(XMLUni::fgDOMValidation, true))
    > parser->setFeature(XMLUni::fgDOMValidation, true);
    > if (parser->canSetFeature(XMLUni::fgDOMNamespaces, true))
    > parser->setFeature(XMLUni::fgDOMNamespaces, true);
    > if (parser->canSetFeature(XMLUni::fgDOMDatatypeNormalization, true))
    > parser->setFeature(XMLUni::fgDOMDatatypeNormalization, true);
    > rootNode = parser->parseURI(xmlFile); // rootNode is a DOMNode*
    > [...]
    > Reading and trying to determine the value type...
    >
    > char* getValue(DOMNode* rootNode, char* elementName) {
    > char* nodeValue = "";
    > try{
    > DOMNodeList* rootElementList = rootNode->getChildNodes();
    > rootNode = rootElementList->item(0);
    > DOMNodeList* subElementList = rootNode->getChildNodes();
    > DOMNode* current = 0;
    > for (unsigned int i=0; i<subElementList->getLength(); i++) {
    > current = subElementList->item(i);
    > if (current->getNodeType() == DOMNode::ELEMENT_NODE) {
    > char* strValue = XMLString::transcode(current->getNodeName());
    > if (XMLString::equals(strValue, elementName)) {
    > nodeValue = XMLString::transcode(current->getFirstChild()->getNodeValue());
    > cout << "Element-Wert:" << nodeValue << endl;
    > cout << "Element-Typ:" << current->getFirstChild()->getNodeType() << endl;
    > //*******************************************************************
    > // it would be great here to determine the type of the
    > // current->getFirstChild() value
    > //*******************************************************************
    > } else {
    > }
    > }
    > }
    > } catch (...) {
    > }
    > return nodeValue;
    > }
    > The xml document:
    > <?xml version="1.0" encoding="ISO-8859-1" ?>
    > <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    > xsi:noNamespaceSchemaLocation="carelis_config.xsd">
    > <nominal>Test eines nominalen Wertes</nominal>
    > <numerical>12221</numerical>
    > </config>
    >
    > The xml schema:
    > <?xml version="1.0" encoding="ISO-8859-1"?>
    > <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
    > <xs:element name="config">
    > <xs:complexType>
    > <xs:sequence>
    > <xs:element name="nominal" type="xs:string"/>
    > <xs:element name="numerical" type="xs:integer"/>
    > </xs:sequence>
    > </xs:complexType>
    > </xs:element>
    > </xs:schema>
    ajm, Apr 21, 2005
    #2
    1. Advertising

  3. Ralph Stuber

    Ralph Stuber Guest

    Hello AJ,

    On 21 Apr 2005 06:32:36 -0700, ajm <> wrote:
    > if i understood correctly it is the XML document (as opposed to the
    > schema which asserts its validity) that you are parsing.


    You understood my intention correctly.

    > to my knowledge it is not possible to do what you want (if anyone has
    > an idea in this direction I am certainly interested in hearing about it)
    > and as a general rule when rolling your own parser you will have to
    > build in document "intelligence" e.g., if element name = "numerical"
    > then parse as int etc. working on the assumption that this is in fact
    > true (i.e., that the document successfully validates)


    In the meantime I implemented a method getType(DOMNode* node) that
    determines the type of node by executing several steps:

    First, it looks for the schema file name given in the xml node named
    "config". Then, it parses the schema file in order to find the
    corresponding node definition given in the schema file defining the
    element found. After having found, it parses the "type" attribute, and
    returns an enum indicating its type (STRING,INTEGER,DATE,...). A struct
    containing the enum value and a void* pointer to the child value of the
    selected xml node will be returned by the getValue() method. Based on
    these two objects, an int* or a char* pointer can be casted from the
    void*-pointer after querying the type from the enum object.

    This way, it is (sophisticatedly) possible to determine the type of
    every node of an xml document, assuming that every element with the same
    name has the same type, and assuming that the name and path of the
    corresponding schema file is known.

    Thank You anyway, greetings from Oldenburg, Germany

    Ralph
    --
    **** COMMODORE 64 BASIC V2 ****
    64K RAM SYSTEM 38911 BASIC BYTES FREE
    READY
    #
    Ralph Stuber, Apr 22, 2005
    #3
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. max_ny

    Determine datatype

    max_ny, Jan 12, 2006, in forum: Java
    Replies:
    9
    Views:
    853
    Eric Sosman
    Jan 13, 2006
  2. Jeff
    Replies:
    2
    Views:
    1,146
    Steve C. Orr [MCSD, MVP, CSM, ASP Insider]
    Apr 16, 2007
  3. Meal
    Replies:
    0
    Views:
    398
  4. Chandra
    Replies:
    2
    Views:
    1,074
    Michael DOUBEZ
    Jul 28, 2008
  5. Peña, Botp
    Replies:
    1
    Views:
    231
    Robert Klemme
    Jan 24, 2004
Loading...

Share This Page