XmlDocument parsing of valid xml file returns no attributes but also no parsing error

I’m trying to parse a xml to be able to read and modify its values. The issue is, when parsing the document sometimes it works. But sometimes it returns only the correct tag name but no attributes at all (when checking the object in visual studio) and doc.getLastParseError() is always empty.

The problem is, the attributes are there and I can get the correct values when looping through them as well. But e->getDoubleAttribute("BPM"); throws an access violation reading location or an access write violation.

Has anyone an idea why this is happening?

xml file

<?xml version="1.0" encoding="UTF-8"?>

<PROPERTIES>
  <VALUE name="37ad5c7bd709f12d4b4706b5bd5374e35c55488682ebc1ce4846fbd17b7602e9">
    <TrackInfo Name="Frucht_on_Ullman_Clean" URL="C:\Users\HAL 9000\Downloads\Frucht_on_Ullman_Clean.wav"
               Length="42.59999847412109" BPM="112.3600006103516" FirstBeatTime="0.064"
               CuePoint1="-1.0" CuePoint2="-1.0" CuePoint3="-1.0" CuePoint4="-1.0"/>
  </VALUE>
</PROPERTIES>
std::unique_ptr<juce::PropertiesFile> trackList

.cpp

float XMLManager::getTrackBpm(const juce::String hash)
{
    if (/trackList.get() != nullptr/trackList->isValidFile()) {
        juce::XmlDocument doc(trackList->getValue(hash));
        std::unique_ptr<juce::XmlElement> e = doc.getDocumentElement(true);
        juce::String b = doc.getLastParseError();
        //std::unique_ptr<juce::XmlElement> element = trackList->getXmlValue(hash);
        //float r = element->getDoubleAttribute("BPM");
        return e->getDoubleAttribute("BPM");
    }

    //if (element)
        //return element->getDoubleAttribute("BPM");

    return 0.f;
}

Did you solve your problem?

It seems like the error was caused by the unique ptr getting out of scope too early. It also happened when saving the value in a local double variable and returning this.

The solution in the end was to release the unique ptr.

float XMLManager::getTrackBpm(const juce::String hash)
{
    if (trackList->isValidFile()) {
        juce::XmlDocument doc(trackList->getValue(hash));
        std::unique_ptr<juce::XmlElement> e = doc.getDocumentElement(true);
        juce::String b = doc.getLastParseError();
        double d = e->getDoubleAttribute("BPM");
        e.release();
        return d;
    }
}

AFAIK by doing that you create a memory leak!

(At first view your code seems wrong ; i’ll send you an example ASAP).

Quick example that should work (errors are mine)! :wink:

float getTrackBpm (const juce::String& hash) const
{
    const std::unique_ptr<juce::XmlElement> e (properties_->getXmlValue (hash));
        
    if (e && e->hasTagName ("TrackInfo")) {
        jassert (e->hasAttribute ("BPM")); return e->getDoubleAttribute ("BPM", 0.0);
    }
        
    return 0.0f;
}