从C中的一行保存多次出现的strstr()?

时间:2015-06-09 15:30:02

标签: c xml parsing substring strstr

这是我第一次在这里发帖,所以如果格式有点不对,我很抱歉。

基本上我的工作要求我读取XML(带有无效标签,因此使用库可能是不可能的 - 我无法控制XML文件),从标签中获取特定字符串,并将它们输出到CSV。

到目前为止,我已经能够解析程序的一部分,但是当所需的标记在一行中多次出现时,我遇到了问题。

这是XML的一般格式:

<my:LineItem>
            <my:LineNumber>1</my:LineNumber>
            <my:PartNumber></my:PartNumber>
            <my:Quantity>1</my:Quantity>
            <my:UOM>EA</my:UOM>
            <my:UnitCost>1</my:UnitCost>
            <my:ExtendedCost>1</my:ExtendedCost>
            <my:CostCentre>801090 - CG Collab - Feretti -Core 1</my:CostCentre>
            <my:ExpenseCode>86130 - Lab Equipment Rental</my:ExpenseCode>
            <my:CostExpenseMerge>801090.86130</my:CostExpenseMerge>
            <my:Description>123</my:Description>
            <my:Comments>1</my:Comments>
        </my:LineItem><my:LineItem><my:LineNumber>2</my:LineNumber><my:PartNumber></my:PartNumber><my:Quantity>2</my:Quantity><my:UOM>BX</my:UOM><my:UnitCost>2</my:UnitCost><my:ExtendedCost xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">4</my:ExtendedCost><my:CostCentre>800186 University of Maastricht - Bou</my:CostCentre><my:ExpenseCode>86110 - Glass/Plastic Washing S</my:ExpenseCode><my:CostExpenseMerge>800186.86110</my:CostExpenseMerge><my:Description></my:Description><my:Comments>2</my:Comments></my:LineItem><my:LineItem><my:LineNumber>3</my:LineNumber><my:PartNumber></my:PartNumber><my:Quantity>3</my:Quantity><my:UOM>CA</my:UOM><my:UnitCost>3</my:UnitCost><my:ExtendedCost xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">9</my:ExtendedCost><my:CostCentre>800180 J Bartlett PCC – PRONTO Team Grant</my:CostCentre><my:ExpenseCode>81920 - Mechanical Supplies</my:ExpenseCode><my:CostExpenseMerge>800180.81920</my:CostExpenseMerge><my:Description></my:Description><my:Comments>3</my:Comments></my:LineItem>

我只需要保存特定值,例如Quantity,CostExpenseMerge和Description。

现在;到目前为止,我能够读取前两次出现,因为它们出现在不同的行上。我现在的问题是:如何在一行中保存多个我想要的标签?

XML似乎随机强制多行进入一行(参见输入文件中的第2和第3项)。

这就是我阅读的内容:

char buffer[1024];
    const char * startTag = "<my:Quantity>";
    const char * endTag = "</my:Quantity>";
    char * start, * end;
    char * tempString, * target=NULL;

while(fgets(buffer, sizeof(buffer), entry_file)){

        if((start=strstr(buffer,startTag))){
                start+=strlen(startTag);
                if((end=strstr(start,endTag))){
                    target = (char*)malloc(end-start+1);
                    memcpy(target, start, end-start);
                    target[end-start]='\0';
                    if(target)printf("%s\n", target);   
                }
        }
        }

我的输出是:

1
2

这意味着第三次出现没有被读取(它应该是“3”)。

请帮忙!

2 个答案:

答案 0 :(得分:0)

您必须在循环中处理标记,因为一行上可以有多个标记:

while(fgets(buffer, sizeof(buffer), entry_file)){
        start= buffer;
        while ((start=strstr(start,startTag))){
                start+=strlen(startTag);
                if((end=strstr(start,endTag))){
                    target = (char*)malloc(end-start+1);
                    memcpy(target, start, end-start);
                    target[end-start]='\0';
                    if(target)printf("%s\n", target);   
                    start= end+strlen(endtag);
                }
                else break;
        }
}

答案 1 :(得分:0)

而不是if(),请使用while()。这是一个适用于您的数据的测试程序:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char buffer[1024];
const char * startTag = "<my:Quantity>";
const char * endTag = "</my:Quantity>";
char * start, * end;
char * tempString, * target=NULL;
int line_offset = 0;

int main( int argc, char* argv[] )
{
    FILE* xml = fopen( "data.xml", "r" );

    if( xml == NULL )
    {
        fprintf( stderr, "Could not load data.xml\n" );
        exit( EXIT_FAILURE );
    }

    while(fgets(buffer, sizeof(buffer), xml)){
        line_offset = 0;
        while((start=strstr(&buffer[line_offset],startTag))){
                start+=strlen(startTag);
                if((end=strstr(start,endTag))){
                    target = (char*)malloc(end-start+1);
                    memcpy(target, start, end-start);
                    target[end-start]='\0';
                    if(target)printf("%s\n", target);
                }

            line_offset += start - buffer;
        }
    }
}