如何从COM中的xml中获取字符串

时间:2013-10-29 14:18:19

标签: c++ com

我有一个这样的数组:

static WCHAR FilesToShow[][100] = { { L"start.cmd" },{ L"image.xml" }, { L"xyz" }};

因为你看到有“xyz”,我必须用一些独特的名字替换它。为此,我必须阅读image.xml文件。

请告诉我怎么办呢。

我写了一个像这样的方法:

PRIVATE WCHAR GetSystemName(WCHAR *pName)

{
    WCHAR line;

    wfstream in("image.xml");
    WCHAR tmp; 

    bool begin_tag = false;
    while (getline(in,line))
    {
        // strip whitespaces from the beginning
        for (int i = 0; i < line.length(); i++)
        {
            if (line[i] == ' ' && tmp.size() == 0)
            {
            }
            else
            {
                tmp += line[i];
            }
        }        

        if (wcswcs(tmp,"<SystemPath>") != NULL)
        {    
           ???????? how to get "vikash" from here <SystemPath>C:\Users\rs_user\Documents\RobotStudio\Systems\vikash</SystemPath>
        }
        else
        {
            continue;
        }

    }

    return tmp;
}

我对wfstream,getline和line.length()方法有异常。 我已经包含了fstream.h头文件,但我认为它在COM中不受支持。

如果不解析xml文件,请帮助我解决此问题。

3 个答案:

答案 0 :(得分:0)

如果您的xml文件足够简单,以便只有一个具有给定名称的标记,您可以这样做:

#include <string>
#include <sstream>
#include <iostream>

std::wstring get_value(std::wistream & in, std::wstring const & tagname)
{
  std::wstring text = std::wstring(std::istreambuf_iterator<std::wstring::value_type>(in),
                                   std::istreambuf_iterator<std::wstring::value_type>());

  std::wstring start_tag = L"<" + tagname + L">";
  std::wstring end_tag = L"</" + tagname + L">";

  std::wstring::size_type start = text.find(start_tag);
  if (start == std::wstring::npos)
  {
    throw 123;
  }
  start += start_tag.length();

  std::wstring::size_type end = text.find(end_tag);
  if (end == std::wstring::npos)
  {
    throw 123;
  }
  return text.substr(start, end - start);
}

std::wstring get_substr_after(std::wstring const & str, wchar_t delim)
{
  std::wstring::size_type pos = str.rfind(delim);
  if (pos == std::wstring::npos)
  {
    throw 123;
  }
  return str.substr(pos + 1);
}


void stackoverflow()
{
  std::wstring text(L"<foo>\n<bar>abc/def/ghi</bar>\n<baz>123/456/789</baz>\n</foo>\n");
  std::wistringstream wiss(text);

  std::wcout << text << std::endl;
  std::wcout << get_substr_after(get_value(wiss, std::wstring(L"bar")), L'/') << std::endl;

}

该程序的输出是:

<foo>
<bar>abc/def/ghi</bar>
<baz>123/456/789</baz>
</foo>

ghi

我希望能回答你的问题。

答案 1 :(得分:0)

你有几个问题。

  1. 你得到的是编译器错误而不是例外
  2. 要包含的头文件是'fstream'而不是'fstream.h'。
  3. 确保您有一句话using namespace std;
  4. 您将line声明为WCHAR类型的变量,因此它是一个宽字符,肯定不是wstring对象。因此line.length()不正确。
  5. 为什么要混用C(wcswcs())和C ++(STL)?也许你应该重新设计你的功能签名。
  6. 但是,请尝试以下功能。我修改了签名以返回指向WCHAR的指针,并将请求的字符串放在pName提供的缓冲区空间中。我添加了一个检查,以验证缓冲区是否足够大,以适应名称和终止NULL字符。

    WCHAR* GetSystemName(WCHAR *pName, size_t buflen)
    {
        wstring line;
        wifstream in("image.xml");
        WCHAR* tmp = NULL;
    
        while (getline(in,line))
        {
            // strip whitespaces from the beginning
            size_t beg_non_whitespace = line.find_first_not_of(L" \t");
            if (beg_non_whitespace != wstring::npos)
            {
                line = line.substr( beg_non_whitespace );
            }
    
            size_t beg_system_path = line.find( L"<SystemPath>" );
            if ( beg_system_path != wstring::npos )
            {    
                // strip the tags (assuming closing tag is present)
                size_t beg_data = beg_system_path + wstring( L"<SystemPath>" ).length();
                size_t range = line.find( L"</SystemPath>" ) - beg_data;
                line = line.substr( beg_data, range );
    
                // get file name
                size_t pos_last_backslash = line.find_last_of( L'\\' );
    
                if ( pos_last_backslash != wstring::npos )
                {
                    line = line.substr( pos_last_backslash + 1 );
    
                    if ( buflen <= line.length() )
                    {
                        // ERROR: pName buffer is not large enough to fit the string + terminating NULL character.
                        return NULL;
                    }
    
                    wcscpy( pName, line.c_str() );
                    tmp = pName;
                    break;
                }
            }
        }
    
        return tmp;
    }
    

    编辑:此外,如果您在程序的其他区域使用和/或解析XML,我强烈建议您使用XML解析库,例如Xerces-C或{{3} }。

答案 2 :(得分:0)

谢谢大家的回答。在这里,我得到了我的问题的解决方案。

PRIVATE WCHAR * GetNewSystemName() {

    WCHAR line[756];
    WCHAR tempBuffer[100];

CComBSTR path = CurrentFolder.Path();

CComBSTR imagePath1 = L"rimageinfo.xml";


path.AppendBSTR(imagePath1);



    std::wfstream in(path);



WCHAR tmp[756]; 



in.getline(line, 756);

WCHAR* buffer;



buffer = wcswcs(line, L"<SystemPath>");
WCHAR *dest = wcsstr(buffer, L"</SystemPath>");
    int pos;
    pos = dest - buffer;
unsigned int i = 0;
if (wcswcs(buffer,L"<SystemPath>") != NULL && wcswcs(buffer,L"</SystemPath>") != NULL)
{ 
    for (; i < pos; i++)
    {
        if (buffer[i] == ' ' && sizeof(tmp) == 0)
        {
        }
        else
        {
            tmp[i] = buffer[i]; 

        }
    }

    tmp[i] = NULL;
    //break;
}

int j = i;

for (; j > 0; j--)
{
    if (tmp[j] == '\\')
    {

        break;
    }
}

j++;    
int k = 0;
for (; j < i ; j++)
{
    System_Name[k] = tmp[j];
    k++;
}

System_Name[k] = NULL;
   return System_Name;