00001 #include "LinguisticDefinition/XmlLingFeaturesFormatter.h"
00002
00003 using namespace std;
00004 using namespace LinguisticDefinition;
00005
00009 XmlLingFeaturesFormatter::XmlLingFeaturesFormatter(const LingDef &lingDef) :
00010 LingFeaturesFormatter(lingDef) {
00011 }
00012
00016 LingFeatures
00017 XmlLingFeaturesFormatter::createLingFeatures(const string &xmlData) {
00018 LingFeatures features(getLingDef());
00019 populateLingFeatures(xmlData, features);
00020 return features;
00021 }
00022
00026 LingFeatures
00027 XmlLingFeaturesFormatter::createLingFeatures(xmlNodePtr featuresNode) {
00028 LingFeatures features(getLingDef());
00029 populateLingFeatures(featuresNode, features);
00030 return features;
00031 }
00032
00036 bool XmlLingFeaturesFormatter::populateLingFeatures(const string &xmlData,
00037 LingFeatures &features) {
00038 bool populationOk = false;
00039 xmlDocPtr doc = xmlParseDoc((xmlChar *) xmlData.c_str());
00040 if (doc != NULL) {
00041 xmlXPathContextPtr xpContext = xmlXPathNewContext(doc);
00042 xmlXPathObjectPtr xpObj =
00043 xmlXPathEvalExpression((xmlChar *) "//LingFeatures", xpContext);
00044 if (xpObj != NULL) {
00045 xmlNodeSetPtr nodeSet = xpObj->nodesetval;
00046 if (nodeSet != NULL && nodeSet->nodeNr > 0) {
00047 populateLingFeatures(nodeSet->nodeTab[0], features);
00048 }
00049 xmlXPathFreeObject(xpObj);
00050 }
00051
00052 xmlXPathFreeContext(xpContext);
00053 xmlFreeDoc(doc);
00054 }
00055 return populationOk;
00056 }
00057
00061 bool XmlLingFeaturesFormatter::populateLingFeatures(xmlNodePtr featuresNode,
00062 LingFeatures &features) {
00063 bool populationOk = true;
00064
00065 const LingDef::Pos *posDef = NULL;
00066 {
00067 xmlChar *tmp = xmlGetProp(featuresNode, (xmlChar *) "pos");
00068 if (tmp != NULL) {
00069 posDef = getLingDef().getPos((char *) tmp);
00070 xmlFree(tmp);
00071 }
00072 }
00073
00074 if (posDef == NULL) {
00075
00076 populationOk = false;
00077
00078 } else {
00079 features.setPosDef(*posDef);
00080
00081 xmlXPathContextPtr xpContext = xmlXPathNewContext(featuresNode->doc);
00082 xpContext->node = featuresNode;
00083
00084 features.setDefaults();
00085
00086 {
00087 xmlXPathObjectPtr xpObj = xmlXPathEval((xmlChar *) "Lemma",
00088 xpContext);
00089 if (xpObj != NULL) {
00090 xmlNodeSetPtr nodeSet = xpObj->nodesetval;
00091 if (nodeSet != NULL && nodeSet->nodeNr > 0) {
00092 xmlChar *tmp = xmlNodeGetContent(nodeSet->nodeTab[0]);
00093 if (tmp != NULL) {
00094 features.setLemma((char *) tmp);
00095 xmlFree(tmp);
00096 }
00097 }
00098 xmlXPathFreeObject(xpObj);
00099 }
00100 }
00101
00102 {
00103 xmlXPathObjectPtr xpObj = xmlXPathEval((xmlChar *) "Form",
00104 xpContext);
00105 if (xpObj != NULL) {
00106 xmlNodeSetPtr nodeSet = xpObj->nodesetval;
00107 if (nodeSet != NULL && nodeSet->nodeNr > 0) {
00108 xmlChar *tmp = xmlNodeGetContent(nodeSet->nodeTab[0]);
00109 if (tmp != NULL) {
00110 features.setForm((char *) tmp);
00111 xmlFree(tmp);
00112 }
00113 }
00114 xmlXPathFreeObject(xpObj);
00115 }
00116 }
00117
00118 xmlXPathObjectPtr xpObj = xmlXPathEval((xmlChar *) "Feature",
00119 xpContext);
00120 if (xpObj != NULL) {
00121 xmlNodeSetPtr nodeSet = xpObj->nodesetval;
00122 if (nodeSet != NULL) {
00123 {for (int i = 0; i < nodeSet->nodeNr; i++) {
00124 xmlNodePtr featureNode = nodeSet->nodeTab[i];
00125 string featureName;
00126 {
00127 xmlChar *tmp = xmlGetProp(featureNode, (xmlChar *) "name");
00128 if (tmp != NULL) {
00129 featureName = (char *) tmp;
00130 xmlFree(tmp);
00131 }
00132 }
00133
00134 const LingDef::Feature *feature =
00135 posDef->getFeature(featureName);
00136 if (feature == NULL) {
00137
00138 populationOk = false;
00139
00140 } else {
00141
00142 if (feature->getType() == LingDef::Feature::BOOLEAN) {
00143 features.set(*feature);
00144
00145 } else if (feature->getType() == LingDef::Feature::ENUM ||
00146 feature->getType() ==
00147 LingDef::Feature::REFERENCE) {
00148 xmlXPathContextPtr xpContext2 =
00149 xmlXPathNewContext(featureNode->doc);
00150 xpContext2->node = featureNode;
00151
00152 xmlXPathObjectPtr xpObj2 =
00153 xmlXPathEval((xmlChar *) "Value", xpContext2);
00154 if (xpObj2 != NULL) {
00155 xmlNodeSetPtr nodeSet2 = xpObj2->nodesetval;
00156 if (nodeSet2 != NULL) {
00157 {for (int j = 0; j < nodeSet2->nodeNr; j++) {
00158 xmlNodePtr valueNode = nodeSet2->nodeTab[j];
00159 string valueValue;
00160 {
00161 xmlChar *tmp = xmlNodeGetContent(valueNode);
00162 if (tmp != NULL) {
00163 valueValue = (char *) tmp;
00164 xmlFree(tmp);
00165 }
00166 }
00167
00168 if (feature->getType() == LingDef::Feature::ENUM) {
00169 const LingDef::Feature *valueFeature =
00170 posDef->getFeature(valueValue);
00171 if (valueFeature == NULL) {
00172
00173 populationOk = false;
00174
00175 } else {
00176 if (valueFeature->getParentEnum() != feature) {
00177
00178 populationOk = false;
00179
00180 } else {
00181 features.set(*valueFeature);
00182 }
00183 }
00184
00185 } else {
00186 int referenceValue = 0;
00187 {
00188 string referenceValueS;
00189 if (valueValue != "" && valueValue[0] == '$') {
00190 referenceValueS = valueValue.substr(1);
00191 } else {
00192 referenceValueS = valueValue;
00193 }
00194 referenceValue = atoi(referenceValueS.c_str());
00195 }
00196
00197 if (referenceValue != 0) {
00198 features.setReference(*feature, referenceValue);
00199 }
00200 }
00201 }}
00202 }
00203 xmlXPathFreeObject(xpObj2);
00204 }
00205 xmlXPathFreeContext(xpContext2);
00206 }
00207 }
00208 }}
00209 }
00210 xmlXPathFreeObject(xpObj);
00211 }
00212 xmlXPathFreeContext(xpContext);
00213 }
00214
00215 return populationOk;
00216 }
00217
00221 void XmlLingFeaturesFormatter::output(const LingFeatures &features,
00222 ostream &out) const {
00223 xmlOutputBufferPtr b = xmlAllocOutputBuffer(NULL);
00224 xmlTextWriterPtr writer = xmlNewTextWriter(b);
00225 output(features, writer);
00226 out << xmlBufferContent(b->buffer);
00227 xmlFreeTextWriter(writer);
00228 }
00229
00233 void XmlLingFeaturesFormatter::output(const LingFeatures &features,
00234 xmlTextWriterPtr writer) const {
00235 xmlTextWriterStartElement(writer, (xmlChar *) "LingFeatures");
00236
00237 xmlTextWriterWriteAttribute(writer,
00238 (xmlChar *) "pos",
00239 (xmlChar *) features.getPosDef()->
00240 getName().c_str());
00241
00242 if (features.getForm() != "") {
00243 xmlTextWriterStartElement(writer, (xmlChar *) "Form");
00244 xmlTextWriterWriteString(writer,
00245 (xmlChar *) features.getForm().c_str());
00246 xmlTextWriterEndElement(writer);
00247 }
00248
00249 if (features.getLemma() != "") {
00250 xmlTextWriterStartElement(writer, (xmlChar *) "Lemma");
00251 xmlTextWriterWriteString(writer,
00252 (xmlChar *) features.getLemma().c_str());
00253 xmlTextWriterEndElement(writer);
00254 }
00255
00256 {for (LingFeatures::FeatureIterator it = features.featuresBegin();
00257 it != features.featuresEnd(); ++it) {
00258 const LingDef::Feature *f = *it;
00259
00260 if (f->getType() == LingDef::Feature::BOOLEAN) {
00261 const LingDef::Feature *enumFeature = f->getParentEnum();
00262 if (enumFeature == NULL) {
00263 xmlTextWriterStartElement(writer, (xmlChar *) "Feature");
00264 xmlTextWriterWriteAttribute(writer,
00265 (xmlChar *) "name",
00266 (xmlChar *) f->getName().c_str());
00267 xmlTextWriterEndElement(writer);
00268 }
00269 } else if (f->getType() == LingDef::Feature::ENUM) {
00270 xmlTextWriterStartElement(writer, (xmlChar *) "Feature");
00271 xmlTextWriterWriteAttribute(writer,
00272 (xmlChar *) "name",
00273 (xmlChar *) f->getName().c_str());
00274
00275 set<const LingDef::Feature *> enumValues;
00276 features.getEnumValues(*f, enumValues);
00277
00278 {for (set<const LingDef::Feature *>::iterator
00279 it2 = enumValues.begin();
00280 it2 != enumValues.end(); ++it2) {
00281 xmlTextWriterStartElement(writer, (xmlChar *) "Value");
00282 xmlTextWriterWriteString(writer,
00283 (xmlChar *) (*it2)->getName().c_str());
00284 xmlTextWriterEndElement(writer);
00285 }}
00286
00287 xmlTextWriterEndElement(writer);
00288
00289 } else if (f->getType() == LingDef::Feature::REFERENCE) {
00290 xmlTextWriterStartElement(writer, (xmlChar *) "Feature");
00291 xmlTextWriterWriteAttribute(writer,
00292 (xmlChar *) "name",
00293 (xmlChar *) f->getName().c_str());
00294
00295 vector<int> references;
00296 features.getReferenceList(*f, references);
00297 {for (vector<int>::iterator it2 = references.begin();
00298 it2 != references.end(); ++it2) {
00299 stringstream s;
00300
00301 xmlTextWriterStartElement(writer, (xmlChar *) "Value");
00302 xmlTextWriterWriteString(writer, (xmlChar *) s.str().c_str());
00303 xmlTextWriterEndElement(writer);
00304 }}
00305
00306 xmlTextWriterEndElement(writer);
00307 }
00308 }}
00309
00310 xmlTextWriterEndElement(writer);
00311 }
00312
00316 string
00317 XmlLingFeaturesFormatter::output(const LingFeatures &features) const {
00318 stringstream s;
00319 output(features, s);
00320 return s.str();
00321 }