UE4-XML与JSon的简单读写实现

一、前言

撸主本来想用引用Tinyxml第三方库来做xml文件的读写,后来发现确实有点麻烦了,不如UE4的XmlParser模块中提供的两个类(FastXML、FXmlFile),本例使用FXmlFile。
编译环境:UnrealEngine 4.15.3、 Visual Studio 2015、 Windows 10 x64

创建项目

创建一个空的C++项目,撸主的命名是“TinyxmlTest”, 由于要使用XmlParser模块和JSON模块,所以在.Build.cs文件中添加相应模块:

PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "XmlParser", "JSON" });

接下来的调试将在GameModeBase中声明定义BlueprintCallable函数,然后在蓝图中通过按键调用函数进行测试。

二、XML

读写函数实现

在TinyxmlTestGameModeBase.h中添加#include “XmlParser.h”,之后添加函数声明:

    //创建并写入xml文件
    UFUNCTION(BlueprintCallable, Category = "Xml")
    void CreateXmlParser();

    //读取xml文件
    UFUNCTION(BlueprintCallable, Category = "Xml")
    void ReadXmlParser(const FString &_XmlPath);

在TinyxmlTestGameModeBase.cpp中,实现读写函数定义:

void  ATinyxmlTestGameModeBase::CreateXmlParser()
{
    //创建的xml文件内容,需要符合xml的规则,不符合则无法写入
    const FString _XmlContent = "<DocumentElement>\n<Infor>\n< ID>01 </ID >\n<Name>AB</Name>\n<Content>BCD</Content>\n</Infor>\n</DocumentElement>";
    //以Buffer的方式创建一个XmlFile对象
    FXmlFile* _WriteXml = new FXmlFile(_XmlContent, EConstructMethod::ConstructFromBuffer);
    //创建XmlFile对象失败
    if (_WriteXml == nullptr)
    {
        GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Red, TEXT("创建xml文件失败!"));
        return;
    }
    //保存xml文件到当前工程
    _WriteXml->Save(FPaths::GameDir() + "write01.xml");
    GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Blue, TEXT("创建xml文件成功!"));
}

void ATinyxmlTestGameModeBase::ReadXmlParser(const FString &_XmlPath)
{
    //创建一个XmlFile对象
    FXmlFile* _XmlFile = new FXmlFile(_XmlPath);
    //得到_XmlFile的根节点
    FXmlNode* _RootNode = _XmlFile->GetRootNode();
    //得到根节点下的所有节点
    const TArray<FXmlNode*> _AssetNodes = _RootNode->GetChildrenNodes();
    for (FXmlNode* node : _AssetNodes)
    {
        //得到_AssetNodes下的所有子节点
        const TArray<FXmlNode*> _ChildNodes = node->GetChildrenNodes();
        FString _AssetContent = node->GetContent();
        //打印_AssetNodes内容
        GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Red, _AssetContent);
        for (FXmlNode* node : _ChildNodes)
        {
            FString _ChildContent = node->GetContent();
            //打印_ChildNodes内容
            GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Blue, _ChildContent);
        }       
    }
}

调试

在UE4 Editor中,创建GameModeBase的蓝图类:
这里写图片描述
打开蓝图类,添加节点:
这里写图片描述

创建并写入函数

我们的创建xml函数执行之后会在当前项目目录下生成一个名为write01.xml的文件,测试结果如下:
这里写图片描述
这里写图片描述
这里写图片描述

读取函数

按下R键开始读取,此处我是新建了一个名为xxxml的xml文件,内容如下:
这里写图片描述
执行结果如下:
这里写图片描述

三、JSON

读写函数实现

在TinyxmlTestGameModeBase.h中添加#include “Json.h”,并添加读写成员函数和JsonStr成员变量声明:

public:
    ATinyxmlTestGameModeBase();

    //读取Json文件
    UFUNCTION(BlueprintCallable, Category = "Json")
    void ReadJson();

    //写Json文件
    UFUNCTION(BlueprintCallable, Category = "Json")
    void WriteJson(FString author, int32 age);

private:
    //Json字符串数据
    FString JsonStr;

此处我们还要实现GameModeBase的构造函数,在其中初始化JsonStr。
在TinyxmlTestGameModeBase.cpp中实现函数定义:

ATinyxmlTestGameModeBase::ATinyxmlTestGameModeBase()
{
    //简单Json格式字符串示例
    JsonStr = "[{\"author\":\"Jack\"},{\"age\":\"100\"}]";
}

void ATinyxmlTestGameModeBase::ReadJson()
{
    //创建用于存储Json对象的数组
    TArray< TSharedPtr<FJsonValue> > JsonParsed;

    //读取Json字符串
    TSharedRef< TJsonReader<TCHAR> > JsonReader = TJsonReaderFactory<TCHAR>::Create(JsonStr);
    //解析Json到数组JsonParsedif (FJsonSerializer::Deserialize(JsonReader, JsonParsed))
    {
        //解析结果打印
        GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Blue, TEXT("解析Json成功!"));
        FString FStringAuthor = JsonParsed[0]->AsObject()->GetStringField("author");
        FString FStringAge = JsonParsed[1]->AsObject()->GetStringField("age");
        FString tempString = "author = " + FStringAuthor + " ,age = " + FStringAge;
        GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Red, tempString);
    }
    else
        GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Red, TEXT("解析失败!"));
}

void ATinyxmlTestGameModeBase::WriteJson(FString author, int32 age)
{
    TSharedRef< TJsonWriter<TCHAR, TCondensedJsonPrintPolicy<TCHAR> > > JSonWriter = TJsonWriterFactory<TCHAR, TCondensedJsonPrintPolicy<TCHAR> >::Create(&JsonStr);
    //写入Json数据开始
    JSonWriter->WriteArrayStart();
    JSonWriter->WriteObjectStart();
    FString newAuthor = "Tom";
    JSonWriter->WriteValue(TEXT("author"), author);
    JSonWriter->WriteObjectEnd();
    JSonWriter->WriteObjectStart();
    JSonWriter->WriteValue(TEXT("age"), age);
    JSonWriter->WriteObjectEnd();
    JSonWriter->WriteArrayEnd();
    JSonWriter->Close();
    //写入结束
    GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Red, TEXT("写入Json成功!"));
}

需要注意的是Json的格式问题,此处的Json字符串初始化和读写都是实现了一个2对象数组的Json数据。
不论是读写函数,都分为数组、对象和值,若是格式不符合则会出现无法读取的情况,由于不熟悉Json,撸主在此处卡了半天,最后还是看JSonWriter->WriteArrayStart()和JSonWriter->WriteObjectStart()的源码发现两者写入的不同的,前者会写入一个“[”,后者会写入一个”{“,因此此处写函数为了和初始化的Json字符串统一格式,实现如上。注意Start函数和End函数必须一一对应。

调试

回到我们的UE4 Editor,在之前创建的GameModeBase蓝图类中,添加蓝图节点:
这里写图片描述
接下来编译保存,我们就能在运行之后通过键盘上的J和N实现Json字符串的读写了。还能在蓝图中修改需要写入Json的值。运行结果如下:
这里写图片描述
上图是撸主分别按了J,N,J之后的结果。第一次读取了初始化的Json字符串,显示了”author = Jack, age = 100”,按下N之后显示“写入JSON成功!”,第二次按J读取了更改之后的Json字符串,显示了”author = Tom, age = 25.0”。


参考文章:
http://blog.csdn.net/cartzhang/article/details/43794409

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值