【C#】Soapの戻り値をXmlDocumentを使ってモデル整形する

C#でxmlの戻り値をモデル整形したので、記録用に
戻り値に<code>\<![CDATA[]]></code>があるデータとないデータがあって、xmlをjsonにしてモデル整形する方法ではうまくできなかったので少し困っていた

### バージョンなど
C#: .NET Framework 4.8

## Soapの戻り値

```xml
<SOAP:Envelope xmlns:SOAP="soap-envelope">
    <SOAP:Header></SOAP:Header>
    <SOAP:Body>
        <Result>
            <Status>OK</Status>
            <UserInfo>
                <UserId><![CDATA[001]]></UserId>
                <UserName><![CDATA[Daisuke Yamamoto]]></UserName>
                <Birthday>1984/5/19</Birthday>
                <Email>dYamamoto@nomomo.com</Email>
            </UserInfo>
            <UserInfo>
                <UserId><![CDATA[002]]></UserId>
                <UserName><![CDATA[Kunihiko Suzuki]]></UserName>
                <Birthday>2000/05/15</Birthday>
                <Email>kSuzuki@nomomo.com</Email>
            </UserInfo>
            <UserInfo>
                <UserId><![CDATA[003]]></UserId>
                <UserName><![CDATA[Hiroaki Sato]]></UserName>
                <Birthday>1988/03/11</Birthday>
                <Email>hSato@nomomo.com</Email>
            </UserInfo>
            <UserInfo>
                <UserId><![CDATA[004]]></UserId>
                <UserName><![CDATA[Keiko Takagi]]></UserName>
                <Birthday>1996/02/10</Birthday>
                <Email>kTakagi<@nomomo.com/Email>
            </UserInfo>
            <UserInfo>
                <UserId><![CDATA[005]]></UserId>
                <UserName><![CDATA[Hitomi Ueda]]></UserName>
                <Birthday>1977/11/19</Birthday>
                <Email>hUeda@nomomo.com</Email>
            </UserInfo>
            <UserInfo>
                <UserId><![CDATA[006]]></UserId>
                <UserName><![CDATA[Emi Usui]]></UserName>
                <Birthday>1980/10/02</Birthday>
                <Email>eUsui@nomomo.com</Email>
            </UserInfo>
        </Result>
    </SOAP:Body>
</SOAP:Envelope>
```

## UserInfo型

```cs
public class UserInfo
{
  public string userId {get; set;}
  public string userName {get; set;}
  public string birthday {get; set;}
  public string email {get; set;}
}
```

## 1. XmlのStringをXmlDocument型に変換

```cs
string content = @"<SOAP:Envelope xmlns:SOAP=""soap-envelope""> ... </SOAP:Envelope>";

XmlDocument xmlDocument = new XmlDocument();
xmlDocument.LoadXml(content);
```

## 2. Statusノードを取得する

```cs
XmlNode statusNode = xmlDocument.GetElementsByTagName("Status")[0];
string statusValue = statusNode.InnerText;
// statusValueの中身は"OK"
```

## 3. UserInfoノードを取り出してUserInfo型に整形する

```cs
XmlNodeList userInfoNodeList = xmlDocument.GetElementsByTagName("UserInfo");
List<UserInfo> userInfoList = new List<UserInfo>();
for (var i = 0; i < userInfoNodeList.Count; i++ )
{
  XmlDocument doc = new XmlDocument();
  doc.LeadXml(userInfoNodeList[i].OuterXml);
  // userInfoNodeList[0].OuterXmlで返ってくるのは以下のノード
  // 
  // <UserInfo>
  //     <UserId><![CDATA[001]]></UserId>
  //     <UserName><![CDATA[Daisuke Yamamoto]]></UserName>
  //     <Birthday>1984/5/19</Birthday>
  //     <Email>dYamamoto@nomomo.com</Email>
  // </UserInfo>

  XmlNode xmlNode = doc.DocumentElement;

  // docの子ノード（UserId, UserName, Birthday, Email）のリストを作る
  XmlNodeList childNodeList = newNode.ChildNodes;
  UserInfo userInfo = new UserInfo();

  for (var j = 0; j < childNodeList.Count; j++)
  {
    XmlNode childNode = childNodeList[j];
    switch (childNode.Name)
    {
      case "UserId":
        userInfo.userId = child.InnerText;
        break;
      case "UserName":
        userInfo.userName = child.InnerText;
        break;
      case "Birthday":
        userInfo.birthday = child.InnerText;
        break;
      case "Email":
        userInfo.email = child.InnerText;
        break;
      default:
        break;
    }
  }

  userInfoList.Add(userInfo);
}
```

これでuserInfoListにはUserInfo型に整形されたデータが入っている

## 感想

XDocumentを使う方法もあったみたいだけど、今回はXmlDoxumentのほうが扱いやすかったです
<code>\<![CDATA[]]></code>は<code>XmlNode.InnerText</code>を使うことで回避できたので良かったです
参考にした記事は見つけられませんでした、、