ZTuple ZTBSpec::Criterion::Rep::AsTuple() const { ZTuple result; result.SetString("PropName", fPropName.AsString()); result.SetString("Rel", sStringFromRel(fComparator.fRel)); if (fComparator.fStrength) result.SetInt32("Strength", fComparator.fStrength); if (fTupleValue) result.SetValue("Value", fTupleValue); return result; }
static ZTupleValue sReadTV(ZML::Reader& ml, const string& iName) { // We're sitting just after the begin tag. If there is any // text, suck it into a string and move on. if (ml.Current() == ZML::eToken_Text) { string allText; ZStrimW_String(allText).CopyAllFrom(ml.Text()); ml.Advance(); if (ml.Current() == ZML::eToken_TagEnd) { // We've hit an end tag, so the begin/end tags were wrapping a text value. if (iName != ml.Name()) throw runtime_error("Tags don't match. Wanted: " + iName + ", Got: " + ml.Name()); ml.Advance(); return allText; } // The text following the begin tag was spurious -- it's not representable // in the simplified tuple we're building, so we'll just ignore it. } // Accumulate all child tags into a tuple to be returned. ZTuple result; for (;;) { if (ml.Current() == ZML::eToken_TagBegin) { // We have a nested begin tag. Grab its name and recurse. string name = ml.Name(); ml.Advance(); ZTupleValue theTV = sReadTV(ml, name); result.SetValue(name, theTV); } else if (ml.Current() == ZML::eToken_TagEmpty) { // We have a nested empty tag -- we represent them as null values. string name = ml.Name(); ml.Advance(); result.SetValue(name, ZTupleValue()); } else if (ml.Current() == ZML::eToken_Text) { // We've got some text, but it's interspersed with other // tags and thus doesn't fit our model -- ignore it. ml.Advance(); } else if (ml.Current() == ZML::eToken_TagEnd) { if (iName != ml.Name()) throw runtime_error("Tags don't match. Wanted: " + iName + ", Got: " + ml.Name()); // We've hit the end tag for the tuple, so we // consume it and break out of the loop. ml.Advance(); break; } else { // We've hit the end of the reader, so we also exit the loop. break; } } return result; }