zoukankan      html  css  js  c++  java
  • UE4使用第三方库读写xml文件

    原文链接:http://gad.qq.com/article/detail/7181031  

    本文首发腾讯GAD开发者平台,未经允许,不得转载


    在游戏开发过程中,读写xml几乎已经成为不可或缺的功能,但是由于有一点点的先入为主,当时直接选择了使用c++常用的tinyxml,于是这里就需要引用第三库,其实UE4有一个自带的XmlParser,也可以轻松读写xml。下面我们就看看这两种的方式的详细操作。

    一、准备工作:
    1.用UE4创建一个空模板的C++工程,命名为TinyxmlProject。
    2.https://sourceforge.net/projects/tinyxml/ 在这里下载tinyxml的工程。

    二、XmlParser:
    1.为Build脚本添加XmlParser的模块,用vs打开当前的工程,找到并打开Source/TinyxmlProject/TinyxmlProject.Build.cs脚本,在PublicDependencyModuleNames中添加"XmlParser":
    public TinyxmlProject(TargetInfo Target)
    {
            PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore" , "XmlParser" });
     
            PrivateDependencyModuleNames.AddRange(new string[] {  });
     
     
            // Uncomment if you are using Slate UI
            // PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" });
     
            // Uncomment if you are using online features
            // PrivateDependencyModuleNames.Add("OnlineSubsystem");
            // if ((Target.Platform == UnrealTargetPlatform.Win32) || (Target.Platform == UnrealTargetPlatform.Win64))
            // {
            //      if (UEBuildConfiguration.bCompileSteamOSS == true)
            //      {
            //          DynamicallyLoadedModuleNames.Add("OnlineSubsystemSteam");
            //      }
            // }
    }
    2.在TinyxmlProjectGameMode添加头文件XmlParser.h就开始写第一个功能,创建并写入xml文件,因为之前的Build.cs中添加了模块,我们可以直接在脚本中添加头文件,这里的xml内容注意符合xml的规则,如果不符合就无法写入。
    void ATinyxmlProjectGameMode::CreateXmlParser()
    {
    	//xml的内容
    	const FString _XmlContent = "<DocumentElement>
    <Infor>
    < ID>01 </ID >
    <Name>AB</Name>
    <Content>BCD</Content>
    </Infor>
    </DocumentElement>";
    	//以Buffer的方式构建一个XmlFile对象
    	FXmlFile* _WriteXml = new FXmlFile(_XmlContent, EConstructMethod::ConstructFromBuffer);
    	//保存xml文件 FPaths::GameDir()表示当前工程的路径
    	_WriteXml->Save(FPaths::GameDir() + "test.xml");
    
    	GEngine->AddOnScreenDebugMessage(-1, 10, FColor::Red, "create success!");
    }
    3.然后在BeginPlay中调用CreateXmlParser(),并在ue4中编译运行,就会在工程路径下找到一个test.xml文件,打开就会看见写入了我们之前所输入的内容。

    4.读取xml,具体注释在脚本中:
    void ATinyxmlProjectGameMode::ReadXmlParser(const FString &_XmlPath)
    {
        //创建一个XmlFile的对象
        FXmlFile* _XmlFile = new FXmlFile(*_XmlPath);
        //获取XmlFile的根节点
        FXmlNode* _RootNode = _XmlFile->GetRootNode();
        //获取根节点下的所有子节点
        const TArray assetNodes = _RootNode->GetChildrenNodes();
        for (int i = 0; i < assetNodes.Num(); i++)
        {
            const TArray contentNodes = assetNodes[i]->GetChildrenNodes();
      
            for (int i = 0; i < contentNodes.Num(); i++)
            {
                //获取并打印出节点内容
                FString _TContent = contentNodes[i]->GetContent();
                GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Blue, _TContent);
            }
        }
    }
    5.继续调用编译并打印,在屏幕上就能看见我们所获取的节点内容
    void ATinyxmlProjectGameMode::BeginPlay()
    {
        //xml的路径
        const  FString _xmlpath = FPaths::GameDir() + "test.xml";
        ReadXmlParser(_xmlpath);
    }


    三、tinyxml:
    1.先给一个第三方库的官方wiki,详细的步骤也可以参照这个来看:https://wiki.unrealengine.com/Linking_Static_Libraries_Using_The_Build_System
    2.打开开始下载的tinyxml工程,右键打开属性,因为我这里会使用的64位的平台,需要将tinyxml的平台改为x64。

    3.生成tinyxml工程,并找到生成的tinyxml.lib文件和tinystr.h、tinyxml.h两个头文件,分别复制到ue4工程目录下的TinyxmlProjectThirdPartyLibs和TinyxmlProjectThirdPartyIncludes,这里的工程下的文件夹都是新建的。
    4.在ue4中找到我们最开始更改的TinyxmlProject.Build.cs脚步,我们又需要添加新的配置,这里我就直接给出整个脚本,这里的功能就是替代普通c++工程引用静态库的配置,详细看看都一个意思,只是方式不同而已。
    using System.IO;
    using UnrealBuildTool;
    
    public class TinyxmlProject : ModuleRules
    {
        private string ModulePath
        {
            get { return ModuleDirectory; }
        }
        //第三方库的路径
        private string ThirdPartyPath
        {
            get { return Path.GetFullPath(Path.Combine(ModulePath, "../../ThirdParty/")); }
        }
    
    	public TinyxmlProject(TargetInfo Target)
    	{
    		PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore" , "XmlParser" });
    
    		PrivateDependencyModuleNames.AddRange(new string[] {  });
    
            //头文件目录
            PublicIncludePaths.Add(Path.Combine(ThirdPartyPath, "Includes"));
            //lib文件
            PublicAdditionalLibraries.Add(Path.Combine(ThirdPartyPath, "Libs","tinyxml.lib"));
    
            // Uncomment if you are using Slate UI
            // PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" });
    
            // Uncomment if you are using online features
            // PrivateDependencyModuleNames.Add("OnlineSubsystem");
            // if ((Target.Platform == UnrealTargetPlatform.Win32) || (Target.Platform == UnrealTargetPlatform.Win64))
            // {
            //		if (UEBuildConfiguration.bCompileSteamOSS == true)
            //		{
            //			DynamicallyLoadedModuleNames.Add("OnlineSubsystemSteam");
            //		}
            // }
        }
    }
    5.静态库配置完成后,再脚本中添加tinystr.h、tinyxml.h两个头文件,我们就尝试利用tinyxml的接口读取本地xml,这里主要注意一些变量类型的转换,UE4是自己的一套变量类型,并不适用tinyxml。
    bool ATinyxmlProjectGameMode::ReadXmlFile(const FString &_XmlPath)
    {
        //将TCHAR转换char 并转UTF-8编码  
        int32 iLength = WideCharToMultiByte(CP_UTF8, 0, *_XmlPath, -1, NULL, 0, NULL, NULL);
        char* path = new char[iLength + 1];
        WideCharToMultiByte(CP_UTF8, 0, *_XmlPath, -1, path, iLength, NULL, NULL);
     
        //创建一个XML的文档对象。  
        TiXmlDocument *myDocument = new TiXmlDocument();
        if (myDocument->LoadFile(path))
        {
            //获得根元素  
            TiXmlElement *RootElement = myDocument->RootElement();
     
            //将char转为TCHAR utf-8编码 支持中文  
            const char* outchar = RootElement->Value();
            iLength = MultiByteToWideChar(CP_UTF8, 0, outchar, strlen(outchar) + 1, NULL, 0);
            TCHAR* outTchar = new TCHAR[iLength + 1];
            MultiByteToWideChar(CP_UTF8, 0, outchar, strlen(outchar) + 1, outTchar, iLength);
     
            GEngine->AddOnScreenDebugMessage(-1, 10, FColor::Green, outTchar);
            return true;
        }
        return false;
    }
    6.再次编译调试
    void ATinyxmlProjectGameMode::BeginPlay()
    {
        //xml的路径
        const  FString _xmlpath = FPaths::GameDir() + "test.xml";
        if(!ReadXmlFile(_xmlpath))
            GEngine->AddOnScreenDebugMessage(-1, 10, FColor::Red, "read failed");
    }

    7.这里的操作差不多就测试完了,其他的tinyxml的操作,百度Google一下就知道了。

  • 相关阅读:
    Java中 Jwt
    Python中Jwt
    jwt流程
    Vue Demons
    Vue基础
    Mysql
    MongoDb
    2020/03/07-基础复习day_02
    2020/03/07-基础复习day_01
    基于springboot+dubbo的简易分布式小Demo
  • 原文地址:https://www.cnblogs.com/liang123/p/6325839.html
Copyright © 2011-2022 走看看