juce::Fileクラスのインスタンスと、
const juce::File PresetManager::colorsFile { juce::File::getSpecialLocation(
juce::File::SpecialLocationType::userApplicationDataDirectory)
.getChildFile(ProjectInfo::companyName)
.getChildFile(ProjectInfo::projectName)
.getChildFile("UserSettings")
.getChildFile("Colors.preset")
};
以下のような色の情報をhexで記録しているXmlファイルがあるとします。
<Colors>
<Color quality="Major" hex="ffbe5050"/>
<Color quality="Minor" hex="ffbe5050"/>
<Color quality="minorMajor" hex="ffbe5050"/>
<Color quality="Dominant" hex="ffbe5050"/>
</Colors>
このファイルをreadする場合は、以下のようにします。一番外側のタグ<Colors>は特に指定しなくても勝手にparseしてくれるようです。
std::unique_ptr<juce::XmlElement> colorsData;
void readXml() {
colorsData = juce::XmlDocument::parse(colorsFile);
for(auto* c: colorsData->getChildIterator()) {
DBG(c->getStringAttribute("quality");
}
}
// prints
// Major
// Minor
// minorMajor
// Dominant
二段構造のXmlの作成と読み込みは以下のコード例
if(!colorsFile.existsAsFile()) {
// parent
juce::XmlElement parentXml("DATA");
// controls
auto controlsXml = std::make_unique<juce::XmlElement ("Controls");
auto childXmlSlider = std::make_unique<juce::XmlElement>("Color");
childXmlSlider->setAttribute("control", SLIDER_COLOR);
std::string trackColor = "fff28d11";
childXmlSlider->setAttribute("hex", trackColor);
// update with a method
colorHandler.updateHex(SLIDER_COLOR, trackColor);
controlsXml->addChildElement(childXmlSlider.release());
// chords
auto chordsXml = std::make_unique<juce::XmlElement>("Chords");
auto childXmlMinor = std::make_unique<juce::XmlElement>("Color");
childXmlMinor->setAttribute("quality", MINOR_NAME);
std::string minorColor = "ff3488c3";
childXmlMinor->setAttribute("hex", minorColor);
colorHandler.updateHex(MINOR_NAME, minorColor);
auto childXmlMinorMajor = std::make_unique<juce::XmlElement>("Color");
childXmlMinorMajor->setAttribute("quality", MINOR_MAJOR_NAME);
std::string minMajorColor = "ff4e7e4f";
childXmlMinorMajor->setAttribute("hex", minMajorColor); // greenyellow
colorHandler.updateHex(MINOR_MAJOR_NAME, minMajorColor);
auto childXmlMajor = std::make_unique<juce::XmlElement>("Color");
childXmlMajor->setAttribute("quality", MAJOR_NAME);
std::string majorColor = "ffeeb42b";
childXmlMajor->setAttribute("hex", majorColor); // orange
colorHandler.updateHex(MAJOR_NAME, majorColor);
auto childXmlDominant = std::make_unique<juce::XmlElement>("Color");
std::string dominantColor = "ff7fa080";
childXmlDominant->setAttribute("quality", DOMINANT_NAME);
childXmlDominant->setAttribute("hex", dominantColor); // purple
colorHandler.updateHex(DOMINANT_NAME, dominantColor);
chordsXml->addChildElement(childXmlMinor.release());
chordsXml->addChildElement(childXmlMinorMajor.release());
chordsXml->addChildElement(childXmlMajor.release());
chordsXml->addChildElement(childXmlDominant.release());
parentXml.addChildElement(controlsXml.release());
parentXml.addChildElement(chordsXml.release());
if(!parentXml.writeTo(colorsFile)) {
DBG("Failed to create Colors xml file");
}
} else {
// if exists, read and update hex with it.
// returns the outmost XmlElement*
auto xml = juce::XmlDocument::parse(colorsFile);
if(xml != nullptr) {
for(auto child : xml->getChildIterator()) {
if(child->hasTagName("Controls")) {
for(auto control: child->getChildIterator()) {
const auto name = control->getStringAttribute("control");
const auto hex = control->getStringAttribute("hex");
colorHandler.updateHex(name, hex);
}
}
else if (child->hasTagName("Chords")) {
for(auto chords: child->getChildIterator()) {
const auto name = chords->getStringAttribute("quality");
const auto hex = chords->getStringAttribute("hex");
colorHandler.updateHex(name, hex);
}
}
}
}
}
voicingsFileというxmlファイル内に以下のデータがあるとします。
<DATA>
<Voicings>
<Voicing index="1" name="minor7 11 9top" quality="Minor">
<Voice value="1"/>
<Voice value="11"/>
<Voice value="16"/>
<Voice value="18"/>
<Voice value="27"/>
</Voicing>
<Voicing index="2" name="minor7 11 b3top" quality="Minor">
<Voice value="1"/>
<Voice value="11"/>
<Voice value="18"/>
<Voice value="20"/>
<Voice value="28"/>
</Voicing>
<Voicing index="3" name="minor7 11 11top" quality="Minor">
<Voice value="1"/>
<Voice value="11"/>
<Voice value="16"/>
<Voice value="27"/>
<Voice value="30"/>
</Voicing>
</Voicings>
</DATA>
// auto xmlはTagName "DATA"のxmlElementのunique_ptrです。
auto xml = juce::XmlDocument::parse(voicingsFile);
// auto voicingsXmlはTagName "Voicings"のxmlElementのunique_ptrです。
auto voicingsXml = xml->getChildByName("Voicings");
// child elements からattributeで検索することができます。
auto voicingInInterest = voicingsXml->getChildByAttribute("index", std::to_string(index));
// 削除する場合はremoveChildElementを使います。
voicingsXml->removeChildElement(voicingInInterest, true);