Exemplo n.º 1
0
void CGUIIncludes::ResolveIncludesForNode(TiXmlElement *node)
{
  // we have a node, find any <include file="fileName">tagName</include> tags and replace
  // recursively with their real includes
  if (!node) return;

  // First add the defaults if this is for a control
  CStdString type;
  if (node->ValueStr() == "control")
  {
    type = node->Attribute("type");
    map<CStdString, TiXmlElement>::const_iterator it = m_defaults.find(type);
    if (it != m_defaults.end())
    {
      const TiXmlElement &element = (*it).second;
      const TiXmlElement *tag = element.FirstChildElement();
      while (tag)
      {
        // we insert at the end of block
        node->InsertEndChild(*tag);
        tag = tag->NextSiblingElement();
      }
    }
  }

  TiXmlElement *include = node->FirstChildElement("include");
  while (include && include->FirstChild())
  {
    // have an include tag - grab it's tag name and replace it with the real tag contents
    const char *file = include->Attribute("file");
    if (file)
    { // we need to load this include from the alternative file
      LoadIncludes(g_SkinInfo->GetSkinPath(file));
    }
    const char *condition = include->Attribute("condition");
    if (condition)
    { // check this condition
      if (!g_infoManager.EvaluateBool(condition))
      {
        include = include->NextSiblingElement("include");
        continue;
      }
    }
    CStdString tagName = include->FirstChild()->Value();
    map<CStdString, TiXmlElement>::const_iterator it = m_includes.find(tagName);
    if (it != m_includes.end())
    { // found the tag(s) to include - let's replace it
      const TiXmlElement &element = (*it).second;
      const TiXmlElement *tag = element.FirstChildElement();
      while (tag)
      {
        // we insert before the <include> element to keep the correct
        // order (we render in the order given in the xml file)
        node->InsertBeforeChild(include, *tag);
        tag = tag->NextSiblingElement();
      }
      // remove the <include>tagName</include> element
      node->RemoveChild(include);
      include = node->FirstChildElement("include");
    }
    else
    { // invalid include
      CLog::Log(LOGWARNING, "Skin has invalid include: %s", tagName.c_str());
      include = include->NextSiblingElement("include");
    }
  }

  // run through this element's attributes, resolving any constants
  TiXmlAttribute *attribute = node->FirstAttribute();
  while (attribute)
  { // check the attribute against our set
    if (m_constantAttributes.count(attribute->NameStr()))
      attribute->SetValue(ResolveConstant(attribute->ValueStr()));
    attribute = attribute->Next();
  }
  // also do the value
  if (node->FirstChild() && node->FirstChild()->Type() == TiXmlNode::TEXT && m_constantNodes.count(node->ValueStr()))
    node->FirstChild()->SetValue(ResolveConstant(node->FirstChild()->ValueStr()));
}
Exemplo n.º 2
0
const char* TiXmlElement::Parse
  ( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding )
{
    p = SkipWhiteSpace( p, encoding );
    TiXmlDocument* document = GetDocument();

    if ( !p || !*p )
    {
        if ( document ) document->SetError( TIXML_ERROR_PARSING_ELEMENT, 0, 0, encoding );
        return 0;
    }

    if ( data )
    {
        data->Stamp( p, encoding );
        location = data->Cursor();
    }

    if ( *p != '<' )
    {
        if ( document ) document->SetError( TIXML_ERROR_PARSING_ELEMENT, p, data, encoding );
        return 0;
    }

    p = SkipWhiteSpace( p+1, encoding );

    // Read the name.
    const char* pErr = p;

    p = ReadName( p, &value, encoding );
    if ( !p || !*p )
    {
        if ( document )    document->SetError( TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME, pErr, data, encoding );
        return 0;
    }

    String endTag ("</");
    endTag += value;
    endTag += ">";

    // Check for and read attributes. Also look for an empty
    // tag or an end tag.
    while ( p && *p )
    {
        pErr = p;
        p = SkipWhiteSpace( p, encoding );
        if ( !p || !*p )
        {
            if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, pErr, data, encoding );
            return 0;
        }
        if ( *p == '/' )
        {
            ++p;
            // Empty tag.
            if ( *p  != '>' )
            {
                if ( document ) document->SetError( TIXML_ERROR_PARSING_EMPTY, p, data, encoding );
                return 0;
            }
            return (p+1);
        }
        else if ( *p == '>' )
        {
            // Done with attributes (if there were any.)
            // Read the value -- which can include other
            // elements -- read the end tag, and return.
            ++p;
            // Note this is an Element method, and will set the error if
            // one happens.
            p = ReadValue( p, data, encoding );
            if ( !p || !*p ) {
                // We were looking for the end tag, but found nothing.
                // Fix for [ 1663758 ] Failure to report error on bad XML
                if ( document ) document->SetError( TIXML_ERROR_READING_END_TAG, p, data, encoding );
                return 0;
            }

            // We should find the end tag now
            if ( StringEqual( p, endTag.c_str(), false, encoding ) )
            {
                p += endTag.length();
                return p;
            }
            else
            {
                if ( document ) document->SetError( TIXML_ERROR_READING_END_TAG, p, data, encoding );
                return 0;
            }
        }
        else
        {
            // Try to read an attribute:
            TiXmlAttribute* attrib = new TiXmlAttribute();
            if ( !attrib )
            {
                if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY, pErr, data, encoding );
                return 0;
            }

            attrib->SetDocument( document );
            pErr = p;
            p = attrib->Parse( p, data, encoding );

            if ( !p || !*p )
            {
                if ( document ) document->SetError( TIXML_ERROR_PARSING_ELEMENT, pErr, data, encoding );
                delete attrib;
                return 0;
            }

            // Handle the strange case of double attributes by ignoring
            // all but the last one.
            // sherm 100319: I fixed this
            TiXmlAttribute* node = attributeSet.Find( attrib->NameStr() );
            if ( node )
            {
                node->SetValue( attrib->Value() );
                delete attrib;
            } else
                attributeSet.Add( attrib );
        }
    }
    return p;
}