/// <summary> /// Parses the structure reference. /// </summary> /// <param name="rootElementName"> /// Name of the root element. /// </param> /// <param name="sdmxStructureEnumType"> /// Type of the SDMX structure. /// </param> /// <param name="parser"> /// The parser. /// </param> /// <returns> /// The <see cref="IStructureReference"/>. /// </returns> /// <exception cref="SdmxSemmanticException"> /// DataSet structure reference incomplete, missing agencyId /// or /// Dataset structure reference incomplete, missing maintainableParentId /// or /// Dataset Structure reference invalid, reference does not match <paramref name="sdmxStructureEnumType"/> /// or /// Dataset structure reference invalid, could not process reference, no Ref node or URN node found /// </exception> private static IStructureReference ParseStructureReference(ElementNameTable rootElementName, SdmxStructureEnumType sdmxStructureEnumType, XmlReader parser) { IStructureReference structureReference = null; string text = null; while (parser.Read()) { if (parser.NodeType == XmlNodeType.Element) { ElementNameTable elementName; if (Enum.TryParse(parser.LocalName, out elementName)) { switch (elementName) { case ElementNameTable.Ref: { structureReference = ProcessStructureReferenceRef(sdmxStructureEnumType, parser); } break; } } } else if (parser.NodeType == XmlNodeType.Text) { text = parser.Value; } else if (parser.NodeType == XmlNodeType.EndElement) { string localname = parser.LocalName; if (rootElementName.Is(localname)) { return structureReference; } if (ElementNameTable.URN.Is(localname)) { structureReference = ProcessStructureReferenceUrn(sdmxStructureEnumType, text); } } } throw new SdmxSemmanticException("Dataset structure reference invalid, could not process reference, no Ref node or URN node found"); }
/// <summary> /// Write the specified Element from the given ITextFormatMutableObject /// </summary> /// <param name="element"> /// The TextFormatType Element /// </param> /// <param name="textFormat"> /// The ITextFormatMutableObject to write /// </param> protected void WriteTextFormat(ElementNameTable element, ITextFormatMutableObject textFormat) { this.WriteStartElement(this.DefaultPrefix, element); if (textFormat.TextType != null) { this.TryWriteAttribute(AttributeNameTable.textType, textFormat.TextType.EnumType.ToString()); } if (textFormat.Decimals > -1) { this.TryWriteAttribute(AttributeNameTable.decimals, textFormat.Decimals); } if (textFormat.StartValue < textFormat.EndValue) { this.TryWriteAttribute(AttributeNameTable.startValue, textFormat.StartValue); this.TryWriteAttribute(AttributeNameTable.endValue, textFormat.EndValue); } if (textFormat.Interval > -1) { this.TryWriteAttribute(AttributeNameTable.interval, textFormat.Interval); } this.TryWriteAttribute(AttributeNameTable.isSequence, textFormat.Sequence); if (textFormat.MaxLength > -1) { this.TryWriteAttribute(AttributeNameTable.maxLength, textFormat.MaxLength); } if (textFormat.MinLength > -1) { this.TryWriteAttribute(AttributeNameTable.minLength, textFormat.MinLength); } this.TryWriteAttribute(AttributeNameTable.pattern, textFormat.Pattern); this.WriteEndElement(); }
/// <summary> /// Write common IReferenceInfo elements /// </summary> /// <param name="refBean"> /// The IReferenceInfo to write /// </param> /// <param name="id"> /// The name of the element /// </param> private void WriteCommonRef(IReferenceInfo refBean, ElementNameTable id) { this.TryToWriteElement(this.DefaultNS, ElementNameTable.URN, refBean.URN); this.TryToWriteElement(this.DefaultNS, ElementNameTable.AgencyID, refBean.AgencyId); this.TryToWriteElement(this.DefaultNS, id, refBean.ID); this.TryToWriteElement(this.DefaultNS, ElementNameTable.Version, refBean.Version); }
/// <summary> /// Write annotations /// </summary> /// <param name="element"> /// The root annotations element name /// </param> /// <param name="annotations"> /// The list of annotations to write /// </param> protected void WriteAnnotations(ElementNameTable element, ICollection<IAnnotationMutableObject> annotations) { if (annotations != null && annotations.Count > 0) { if (IsTwoPointOne) { this.WriteStartElement(this.Namespaces.Common, ElementNameTable.Annotations); } else { this.WriteStartElement(this.DefaultNS, element); } foreach (var annotation in annotations) { this.WriteStartElement(this.Namespaces.Common, ElementNameTable.Annotation); if (IsTwoPointOne && !string.IsNullOrEmpty(annotation.Id)) { this.WriteAttributeString("id", annotation.Id); } this.TryToWriteElement(this.Namespaces.Common, ElementNameTable.AnnotationTitle, annotation.Title); this.TryToWriteElement(this.Namespaces.Common, ElementNameTable.AnnotationType, annotation.Type); this.TryToWriteElement(this.Namespaces.Common, ElementNameTable.AnnotationURL, annotation.Uri); if (ObjectUtil.ValidCollection(annotation.Text)) { foreach (var text in annotation.Text) { this.WriteTextType(this.Namespaces.Common, text, ElementNameTable.AnnotationText); } } this._writer.WriteEndElement(); } this._writer.WriteEndElement(); } }
/// <summary> /// Write the given IItemMutableObject type object to the given element. /// </summary> /// <param name="element"> /// The xml element /// </param> /// <param name="item"> /// The IItemMutableObject type object to write /// </param> protected void WriteItem(ElementNameTable element, IItemMutableObject item) { // ReSharper restore SuggestBaseTypeForParameter this.WriteStartElement(this.DefaultPrefix, element); this.WriteIdentifiableArtefactAttributes(item); //// TODO NOTE not supported by common api ////TryWriteAttribute(AttributeNameTable.version, item.Version); ////TryWriteAttribute(AttributeNameTable.validFrom, item.ValidFrom); ////TryWriteAttribute(AttributeNameTable.validTo, item.ValidTo); this.WriteIdentifiableArtefactContent(item); }
/// <summary> /// Write the element if it's value is not empty or null /// </summary> /// <param name="namespacePrefix"> /// The namespace prefix /// </param> /// <param name="element"> /// The <see cref="ElementNameTable"/> element name /// </param> /// <param name="value"> /// The elements text /// </param> protected void TryToWriteElement(NamespacePrefixPair namespacePrefix, ElementNameTable element, Uri value) { if (value != null) { this.WriteElement(namespacePrefix, element, value.ToString()); } }
/// <summary> /// Write the element with it's <c>xs:boolean</c> value if it is true /// </summary> /// <param name="prefix"> /// The namespace prefix /// </param> /// <param name="element"> /// The <see cref="ElementNameTable"/> element name /// </param> /// <param name="value"> /// The elements text /// </param> protected void TryToWriteElement(NamespacePrefixPair prefix, ElementNameTable element, bool value) { if (value) { this.WriteElement(prefix, element, true); } }
/// <summary> /// Write a Start Element to the given XmlTextWriter using the given prefix and the <see cref="ElementNameTable"/> name /// </summary> /// <param name="element"> /// The <see cref="ElementNameTable"/> element name /// </param> /// <param name="ns"> /// The namespace /// </param> protected void WriteStartElement(ElementNameTable element, string ns) { this._writer.WriteStartElement(NameTableCache.GetElementName(element), ns); }
/// <summary> /// This is an internal method that is used to write a <see cref="ITextTypeWrapper"/> /// The method create a xml element named by the name parameter. /// It will only write the xml element if the <see cref="ITextTypeWrapper"/> is not null or empty /// </summary> /// <param name="textObject"> /// The <see cref="ITextTypeWrapper"/> object containing the data to be written /// </param> /// <param name="name"> /// The name of the xml element /// </param> protected void WriteTextType(ITextTypeWrapper textObject, ElementNameTable name) { this.WriteTextType(NamespacePrefixPair.Empty, textObject, name); }
/// <summary> /// Write a Start Element to the given XmlTextWriter using the given prefix and the <see cref="ElementNameTable"/> name /// </summary> /// <param name="ns"> /// The namespace and prefix /// </param> /// <param name="element"> /// The <see cref="ElementNameTable"/> element name /// </param> protected void WriteStartElement(NamespacePrefixPair ns, ElementNameTable element) { this.WriteStartElement(ns, NameTableCache.GetElementName(element)); }
/// <summary> /// Write a Start Element to the given XmlTextWriter using the given prefix and the <see cref="ElementNameTable"/> name /// </summary> /// <param name="prefix"> /// The namespace prefix /// </param> /// <param name="element"> /// The <see cref="ElementNameTable"/> element name /// </param> protected void WriteStartElement(string prefix, ElementNameTable element) { this._writer.WriteStartElement(prefix, NameTableCache.GetElementName(element), null); }
/// <summary> /// This method is used to write the root xml tag and message tag /// with their corresponding attributes /// </summary> /// <param name="message"> /// The message to write /// </param> protected void WriteMessageTag(ElementNameTable message) { if (!this._wrapped) { this._writer.WriteStartDocument(); } this.WriteStartElement(this.Namespaces.Message, message); var namespaces = new[] { this.DefaultNS, this.Namespaces.Message, this.Namespaces.Common, this.Namespaces.Compact, this.Namespaces.Cross, this.Namespaces.Generic, this.Namespaces.Query, this.Namespaces.Structure, this.Namespaces.Utility, this.Namespaces.Registry }; var namespacesWrote = new HashSet<NamespacePrefixPair>(); for (int i = 0; i < namespaces.Length; i++) { NamespacePrefixPair nameSpace = namespaces[i]; if (nameSpace != null && !string.IsNullOrWhiteSpace(nameSpace.NS) && !namespacesWrote.Contains(nameSpace)) { this.WriteNamespaceDecl(nameSpace); namespacesWrote.Add(nameSpace); } } this._writer.WriteAttributeString( XmlConstants.XmlSchemaPrefix, XmlConstants.SchemaLocation, XmlConstants.XmlSchemaNS, this.Namespaces.SchemaLocation); }
/// <summary> /// Write the element with it's <c>xs:boolean</c> value /// </summary> /// <param name="prefix"> /// The namespace prefix /// </param> /// <param name="element"> /// The <see cref="ElementNameTable"/> element name /// </param> /// <param name="value"> /// The elements text /// </param> protected void WriteElement(string prefix, ElementNameTable element, bool value) { this._writer.WriteElementString( prefix, NameTableCache.GetElementName(element), null, XmlConvert.ToString(value)); }
/// <summary> /// Write the element /// </summary> /// <param name="namespacePrefix"> /// The namespace prefix /// </param> /// <param name="element"> /// The element name /// </param> /// <param name="value"> /// The elements text /// </param> protected void WriteElement(NamespacePrefixPair namespacePrefix, ElementNameTable element, string value) { this._writer.WriteElementString( namespacePrefix.Prefix, NameTableCache.GetElementName(element), namespacePrefix.NS, value); }
/// <summary> /// Write the element with it's <c>xs:boolean</c> value /// </summary> /// <param name="namespacePrefix"> /// The namespace prefix /// </param> /// <param name="element"> /// The element name /// </param> /// <param name="value"> /// The elements text /// </param> protected void WriteElement(NamespacePrefixPair namespacePrefix, ElementNameTable element, int value) { this.WriteElement(namespacePrefix, NameTableCache.GetElementName(element), value); }
/// <summary> /// This is an internal method that is used to write the <paramref name="textObject"/> /// The method create a xml element named by the name parameter. /// It will only write the xml element if the text inside <paramref name="textObject"/> is not null or empty /// </summary> /// <param name="namespacePrefix"> /// The namespace prefix pair /// </param> /// <param name="textObject"> /// The <see cref="KeyValuePair{TKey,TValue}"/> object containing the data to be written, where key is the locale and value the text value /// </param> /// <param name="name"> /// The name of the xml element /// </param> protected void WriteTextType( NamespacePrefixPair namespacePrefix, IDictionary<string, string> textObject, ElementNameTable name) { foreach (KeyValuePair<string, string> valuePair in textObject) { this.WriteTextType(namespacePrefix, valuePair, name); } }
/// <summary> /// Write the element if it's value is not empty or null /// </summary> /// <param name="prefix"> /// The namespace prefix /// </param> /// <param name="element"> /// The <see cref="ElementNameTable"/> element name /// </param> /// <param name="value"> /// The elements text /// </param> protected void TryToWriteElement(string prefix, ElementNameTable element, string value) { if (!string.IsNullOrEmpty(value)) { this.WriteElement(prefix, element, value); } }
/// <summary> /// This is an internal method that is used to write the <paramref name="textObject"/> /// The method create a xml element named by the name parameter. /// It will only write the xml element if the text inside <paramref name="textObject"/> is not null or empty /// </summary> /// <param name="namespacePrefix"> /// The namespace Prefix. /// </param> /// <param name="textObject"> /// The <see cref="KeyValuePair{TKey,TValue}"/> object containing the data to be written, where key is the locale and value the text value /// </param> /// <param name="name"> /// The name of the xml element /// </param> protected void WriteTextType( NamespacePrefixPair namespacePrefix, KeyValuePair<string, string> textObject, ElementNameTable name) { this.WriteTextType(namespacePrefix, name, textObject.Value, textObject.Key); }
/// <summary> /// Write the element if it's value is not empty or null /// </summary> /// <param name="prefix"> /// The namespace prefix /// </param> /// <param name="element"> /// The <see cref="ElementNameTable"/> element name /// </param> /// <param name="value"> /// The elements text /// </param> protected void TryToWriteElement(string prefix, ElementNameTable element, Uri value) { if (value != null) { this.WriteElement(prefix, element, value.ToString()); } }
/// <summary> /// This is an internal method that is used to write a <see cref="ITextTypeWrapper" /> /// The method create a XML element named by the name parameter. /// It will only write the XML element if the <see cref="ITextTypeWrapper.Value" /> is not null or empty /// </summary> /// <param name="namespacePrefix">The namespace prefix that should be used</param> /// <param name="textObject">The text object.</param> /// <param name="name">The name.</param> protected void WriteTextType(NamespacePrefixPair namespacePrefix, IList<ITextTypeWrapper> textObject, ElementNameTable name) { if (textObject != null && textObject.Count > 0) { this.WriteTextType(namespacePrefix, textObject[0], name); } }
/// <summary> /// Write the element with it's <c>xs:boolean</c> value if it is true /// </summary> /// <param name="prefix"> /// The namespace prefix /// </param> /// <param name="element"> /// The <see cref="ElementNameTable"/> element name /// </param> /// <param name="value"> /// The elements text /// </param> protected void TryToWriteElement(string prefix, ElementNameTable element, bool value) { if (value) { this.WriteElement(prefix, element, true); } }
/// <summary> /// This is an internal method that is used to write a <see cref="ITextTypeWrapper"/> /// The method create a xml element named by the name parameter. /// It will only write the xml element if the <see cref="ITextTypeWrapper.Value"/> is not null or empty /// </summary> /// <param name="prefix"> /// The namespace prefix that should be used /// </param> /// <param name="textObject"> /// The <see cref="ITextTypeWrapper"/> object containing the data to be written /// </param> /// <param name="name"> /// The name of the xml element /// </param> protected void WriteTextType(string prefix, ITextTypeWrapper textObject, ElementNameTable name) { string value = textObject.Value; string locale = textObject.Locale; this.WriteTextType(new NamespacePrefixPair(prefix), name, value, locale); }
/// <summary> /// The get key values. /// </summary> /// <param name="endElement"> /// The end element. /// </param> /// <returns> /// The <see cref="IList{IKeyValue}"/>. /// </returns> private IList<IKeyValue> GetKeyValues(ElementNameTable endElement) { IList<IKeyValue> returnList = new List<IKeyValue>(); while (this.Parser.Read()) { var nodeType = this.Parser.NodeType; switch (nodeType) { case XmlNodeType.Element: { string nodeName = this.Parser.LocalName; if (ElementNameTable.Value.Is(nodeName)) { string componentVal = this.Parser.GetAttribute(AttributeNameTable.value); if (this.IsTwoPointOne) { returnList.Add(new KeyValueImpl(componentVal, this.Parser.GetAttribute(AttributeNameTable.id))); } else { string componentId = this.GetComponentId(this.Parser.GetAttribute(AttributeNameTable.concept)); returnList.Add(new KeyValueImpl(componentVal, componentId)); } } } break; case XmlNodeType.EndElement: if (endElement.Is(this.Parser.LocalName)) { return returnList; } break; } } return returnList; }
/// <summary> /// This is an internal method that is used to write the <paramref name="value"/> for the specified /// <paramref name="locale"/> /// The method create a XML element named by the name parameter. /// It will only write the XML element if the text inside <paramref name="value"/> is not null or empty /// </summary> /// <param name="namespacePrefix"> /// The namespace prefix /// </param> /// <param name="name"> /// The name of the XML element /// </param> /// <param name="value"> /// The text value. /// </param> /// <param name="locale"> /// The locale. /// </param> protected void WriteTextType( NamespacePrefixPair namespacePrefix, ElementNameTable name, string value, string locale) { if (!string.IsNullOrEmpty(value)) { this._writer.WriteStartElement( namespacePrefix.Prefix, NameTableCache.GetElementName(name), namespacePrefix.NS); if (!string.IsNullOrEmpty(locale)) { this._writer.WriteAttributeString(XmlConstants.XmlPrefix, XmlConstants.LangAttribute, null, locale); } this._writer.WriteString(value); this._writer.WriteEndElement(); } }
/// <summary> /// Write the given IMaintainableMutableObject type object to the given element. /// </summary> /// <param name="element"> /// The xml element /// </param> /// <param name="artefact"> /// The IMaintainableMutableObject type object to write /// </param> protected void WriteMaintainableArtefact(ElementNameTable element, IMaintainableMutableObject artefact) { this.WriteStartElement(this.DefaultPrefix, element); this.WriteMaintainableArtefactAttributes(artefact); this.WriteIdentifiableArtefactContent(artefact); }
/// <summary> /// Write the element if it's value is not empty or null /// </summary> /// <param name="namespacePrefix"> /// The namespace prefix pair /// </param> /// <param name="elementName"> /// The <see cref="ElementNameTable"/> element name /// </param> /// <param name="value"> /// The elements text /// </param> protected void TryToWriteElement( NamespacePrefixPair namespacePrefix, ElementNameTable elementName, DateTime? value) { if (value.HasValue) { this.WriteElement(namespacePrefix, elementName, DateUtil.FormatDate(value.Value)); } }
/// <summary> /// Jumps to node. /// </summary> /// <param name="stream"> /// The stream. /// </param> /// <param name="findNodeName"> /// Name of the find node. /// </param> /// <param name="doNotProcessPastNodeName"> /// Name of the do not process past node. /// </param> /// <param name="throwException"> /// if set to <c>true</c> [throw exception]. /// </param> /// <returns> /// The <see cref="XmlReader"/> at the specific position. /// </returns> /// <exception cref="SdmxSyntaxException"> /// Could not find element: + findNodeName /// </exception> private XmlReader JumpToNode(Stream stream, ElementNameTable findNodeName, string doNotProcessPastNodeName, bool throwException) { using (var parser = this._xmlReaderBuilder.Build(stream)) { bool jumpToNode = StaxUtil.JumpToNode(parser, findNodeName.FastToString(), doNotProcessPastNodeName); if (!jumpToNode && throwException && doNotProcessPastNodeName != null) { throw new SdmxSyntaxException("Could not find element: " + findNodeName); } return null; } }
/// <summary> /// Write the element if it's value is not empty or null /// </summary> /// <param name="namespacePrefix"> /// The namespace prefix pair /// </param> /// <param name="element"> /// The <see cref="ElementNameTable"/> element name /// </param> /// <param name="value"> /// The elements text /// </param> protected void TryToWriteElement(NamespacePrefixPair namespacePrefix, ElementNameTable element, string value) { this.TryToWriteElement(namespacePrefix, NameTableCache.GetElementName(element), value); }
/// <summary> /// Creates an address map from an XML document. /// </summary> /// <param name="xmlDocument">The document to be parsed for addresses</param> /// <param name="documentVersion">Identifies a particular version of the document</param> public AddressMap(XmlDocument xmlDocument, int documentVersion) : base() { // This table is used to quickly map an element name to a token. ElementNameTable elementNameTable = new ElementNameTable(); // These variables are used to track the states when parsing the XML Spreadsheet. int rowType = 0; int rowIndex = 0; int columnIndex = 0; int columnType = 0; int securityId = 0; ParsingState parsingState = ParsingState.None; // IMPORTANT CONCEPT: Create a fast, forward only reader on the XML Document. This saves a lot of time over // trying to use XPath commands on the version used for the document. The main idea is that we are going to // rip through the spreadsheet XML looking only for specific element nodes. Certain elements will cause the // state of the parsing to change (e.g. finding a 'ss:Row' element will increment the row counter. Other // nodes contain data that helps to map the spreadsheet document into a data structure that can be used to // address individual cells in the spreadsheet, which is the end product of this method. XmlNodeReader xmlNodeReader = new XmlNodeReader(xmlDocument); // Rip through the XML file looking for specific node types and names. while (xmlNodeReader.Read()) { // The outer switch statement divides the nodes up into their types. The inner switch statement will // examine their names. We will switch from one state to another based on this combination of node type // and name. The state ultimately tells us how to interpret the data when we run across it. switch (xmlNodeReader.NodeType) { case XmlNodeType.Element: // Turn the element name into a token so we can quickly jump to the code to handle it. switch (elementNameTable[xmlNodeReader.Name]) { case ElementName.NamedRange: // Create a mapping of column names to column types and vica-versa. columnIndex = SpreadsheetColumn.Parse(xmlNodeReader["ss:RefersTo"]); columnType = ColumnType.Tokenize(xmlNodeReader["ss:Name"]); if (columnIndex != SpreadsheetColumn.DoesNotExist && columnType != ColumnType.None) { // Make sure that errors in the column names don't kill the whole parsing session. try { this.ColumnIndexMap.AddColumnIndexMapRow(columnType, columnIndex); this.ColumnIdMap.AddColumnIdMapRow(columnIndex, columnType); } catch (Exception exception) { // Write the error and stack trace out to the debug listener Debug.WriteLine(String.Format("{0}, {1}", exception.Message, exception.StackTrace)); } } break; case ElementName.Row: // Increase the row index monotonically if no explicit index is given. string rowIndexText = xmlNodeReader["ss:Index"]; rowIndex = (rowIndexText == null) ? rowIndex + 1 : Convert.ToInt32(rowIndexText); // Reset the state of the row when we recognize a new row. rowType = RowType.Unused; columnIndex = 0; break; case ElementName.Cell: // Increase the column index monotonically if no explicit index is given. string columnIndexText = xmlNodeReader["ss:Index"]; columnIndex = (columnIndexText == null) ? columnIndex + 1 : Convert.ToInt32(columnIndexText); break; case ElementName.Data: // If we're on the row type column (typically, the first column of every row in the // spreadsheet), then the next Text node will contain the row type. if (columnIndex == GetColumnIndex(ColumnType.RowType)) { parsingState = ParsingState.RowType; break; } // If the current column is a position type code on a position row, then look for the position // type code the next time a Text node is found. if (rowType == RowType.BlockOrder && columnIndex == GetColumnIndex(ColumnType.BlockOrderId)) { parsingState = ParsingState.BlockOrderId; break; } // If the current column is the security id column on a position row, then look for the // security id the next time a Text node is found. if (rowType == RowType.BlockOrder && columnIndex == GetColumnIndex(ColumnType.SecurityId)) { parsingState = ParsingState.SecurityId; break; } break; default: // The parsing state is only good for the scope of the 'Data' element. If we didnt' // recognize a parsing state above, then reset the state value so we don't get confused the // next time we read a 'Data' node. parsingState = ParsingState.None; break; } break; case XmlNodeType.Text: // The state variable tells us how to interpret the text nodes. switch (parsingState) { case ParsingState.RowType: // This node tells us what kind of row we are reading. rowType = Convert.ToInt32(xmlNodeReader.Value); break; case ParsingState.SecurityId: // The security identifier is found in this cell. securityId = Convert.ToInt32(xmlNodeReader.Value); // Construct a map of security locations for the incoming prices. Remember that a single // security could be on the report twice: once for long and once for short positions. Create // the security level row first if it doesn't already exist. AddressMapSet.SecurityMapRow securityMapRow = SecurityMap.FindBySecurityId(securityId); if (securityMapRow == null) { securityMapRow = SecurityMap.AddSecurityMapRow(securityId); } // Last Price Mapping int lastPriceColumnIndex = GetColumnIndex(ColumnType.LastPrice); if (lastPriceColumnIndex != SpreadsheetColumn.DoesNotExist) { LastPriceAddress.AddLastPriceAddressRow(securityMapRow, documentVersion, rowIndex, lastPriceColumnIndex); } // Bid Price Mapping int bidPriceColumnIndex = GetColumnIndex(ColumnType.BidPrice); if (bidPriceColumnIndex != SpreadsheetColumn.DoesNotExist) { BidPriceAddress.AddBidPriceAddressRow(securityMapRow, documentVersion, rowIndex, bidPriceColumnIndex); } // Ask Price Mapping int askPriceColumnIndex = GetColumnIndex(ColumnType.AskPrice); if (askPriceColumnIndex != SpreadsheetColumn.DoesNotExist) { AskPriceAddress.AddAskPriceAddressRow(securityMapRow, documentVersion, rowIndex, askPriceColumnIndex); } break; case ParsingState.BlockOrderId: // The position type code is found in this cell. int blockOrderId = Convert.ToInt32(xmlNodeReader.Value); // Construct a map entry for cell that is addressed by a security, position type code // combination. Note how the columns are mapped dynamically based on the names given to the // columns in the spreadsheet. See the section above that extracts the column names for how // the column index is constructed. BlockOrderMap.AddBlockOrderMapRow(blockOrderId, ColumnType.StatusCode, documentVersion, rowIndex, GetColumnIndex(ColumnType.StatusCode)); BlockOrderMap.AddBlockOrderMapRow(blockOrderId, ColumnType.QuantityOrdered, documentVersion, rowIndex, GetColumnIndex(ColumnType.QuantityOrdered)); BlockOrderMap.AddBlockOrderMapRow(blockOrderId, ColumnType.QuantityPlaced, documentVersion, rowIndex, GetColumnIndex(ColumnType.QuantityPlaced)); BlockOrderMap.AddBlockOrderMapRow(blockOrderId, ColumnType.QuantityExecuted, documentVersion, rowIndex, GetColumnIndex(ColumnType.QuantityExecuted)); break; } // Reset the parsing state after each text node is read and interpreted. parsingState = ParsingState.None; break; } } // Commit all the changes made to the data set. this.AcceptChanges(); }
/// <summary> /// Write the element if it's value is not empty or null /// </summary> /// <param name="element"> /// The <see cref="ElementNameTable"/> element name /// </param> /// <param name="value"> /// The elements text /// </param> protected void TryToWriteElement(ElementNameTable element, string value) { this.TryToWriteElement(NamespacePrefixPair.Empty, element, value); }
/// <summary> /// Processes the party. /// </summary> /// <param name="rootElementName"> /// Name of the root element. /// </param> /// <param name="parser"> /// The parser. /// </param> /// <returns> /// The <see cref="IParty"/>. /// </returns> /// <exception cref="System.InvalidOperationException"> /// Could not find end element specified at /// <paramref name="rootElementName"/> /// </exception> private static IParty ProcessParty(ElementNameTable rootElementName, XmlReader parser) { bool isEmptyElement = parser.IsEmptyElement; string id = parser.GetAttribute(AttributeNameTable.id); string timeZone = null; var nameMap = new List<ITextTypeWrapper>(); var contacts = new List<IContact>(); string text = null; string xmlLang = null; if (!isEmptyElement) { while (parser.Read()) { if (parser.NodeType == XmlNodeType.Element) { xmlLang = parser.XmlLang; ElementNameTable elementName; if (Enum.TryParse(parser.LocalName, out elementName)) { switch (elementName) { case ElementNameTable.Contact: contacts.Add(ProcessContact(parser)); break; } } } else if (parser.NodeType == XmlNodeType.Text) { text = parser.Value; } else if (parser.NodeType == XmlNodeType.EndElement) { if (rootElementName.Is(parser.LocalName)) { break; } ElementNameTable elementName; if (Enum.TryParse(parser.LocalName, out elementName)) { switch (elementName) { case ElementNameTable.Name: AddItemToLang(nameMap, text, xmlLang); break; // NOTE .NET uses the correct "Timezone" name. In Java it uses the incorrect "TimeZone" which does not exist! PLEASE double check with SDMX v2.1 SDMXMessage.xsd before changing. case ElementNameTable.Timezone: timeZone = text; break; } } } } } return new PartyCore(nameMap, id, contacts, timeZone); }
/// <summary> /// Creates an address map from an XML document. /// </summary> /// <param name="xmlDocument">The document to be parsed for addresses</param> /// <param name="documentVersion">Identifies a particular version of the document</param> public AddressMap(XmlDocument xmlDocument, int documentVersion) : base() { // This table is used to quickly map an element name to a token. ElementNameTable elementNameTable = new ElementNameTable(); // These variables are used to track the states when parsing the XML Spreadsheet. int rowType = 0; int rowIndex = 0; int columnIndex = 0; int columnType = 0; ParsingState parsingState = ParsingState.None; // IMPORTANT CONCEPT: Create a fast, forward only reader on the XML Document. This saves a lot of time over // trying to use XPath commands on the version used for the document. The main idea is that we are going to // rip through the spreadsheet XML looking only for specific element nodes. Certain elements will cause the // state of the parsing to change (e.g. finding a 'ss:Row' element will increment the row counter. Other // nodes contain data that helps to map the spreadsheet document into a data structure that can be used to // address individual cells in the spreadsheet, which is the end product of this method. XmlNodeReader xmlNodeReader = new XmlNodeReader(xmlDocument); // Rip through the XML file looking for specific node types and names. while (xmlNodeReader.Read()) { // The outer switch statement divides the nodes up into their types. The inner switch statement will // examine their names. We will switch from one state to another based on this combination of node type // and name. The state ultimately tells us how to interpret the data when we run across it. switch (xmlNodeReader.NodeType) { case XmlNodeType.Element: // Turn the element name into a token so we can quickly jump to the code to handle it. switch (elementNameTable[xmlNodeReader.Name]) { case ElementName.NamedRange: // Create a mapping of column names to column types and vica-versa. columnIndex = SpreadsheetColumn.Parse(xmlNodeReader["ss:RefersTo"]); columnType = TicketColumnType.Tokenize(xmlNodeReader["ss:Name"]); if (columnIndex != SpreadsheetColumn.DoesNotExist && columnType != TicketColumnType.None) { // Make sure that errors in the column names don't kill the whole parsing session. try { this.ColumnIndexMap.AddColumnIndexMapRow(columnType, columnIndex); this.ColumnIdMap.AddColumnIdMapRow(columnIndex, columnType); } catch (Exception exception) { // Write the error and stack trace out to the debug listener Debug.WriteLine(String.Format("{0}, {1}", exception.Message, exception.StackTrace)); } } break; case ElementName.Row: // Increase the row index monotonically if no explicit index is given. string rowIndexText = xmlNodeReader["ss:Index"]; rowIndex = (rowIndexText == null) ? rowIndex + 1 : Convert.ToInt32(rowIndexText); // Reset the state of the row when we recognize a new row. rowType = TicketRowType.Unused; columnIndex = 0; break; case ElementName.Cell: // Increase the column index monotonically if no explicit index is given. string columnIndexText = xmlNodeReader["ss:Index"]; columnIndex = (columnIndexText == null) ? columnIndex + 1 : Convert.ToInt32(columnIndexText); break; case ElementName.Data: // If we're on the row type column (typically, the first column of every row in the // spreadsheet), then the next Text node will contain the row type. if (columnIndex == GetColumnIndex(TicketColumnType.RowType)) { parsingState = ParsingState.RowType; break; } // If the current column is a position type code on a position row, then look for the position // type code the next time a Text node is found. if (rowType == TicketRowType.GlobalTicket && columnIndex == GetColumnIndex(TicketColumnType.ExecutionId)) { parsingState = ParsingState.GlobalTicketId; break; } break; default: // The parsing state is only good for the scope of the 'Data' element. If we didnt' // recognize a parsing state above, then reset the state value so we don't get confused the // next time we read a 'Data' node. parsingState = ParsingState.None; break; } break; case XmlNodeType.Text: // The state variable tells us how to interpret the text nodes. switch (parsingState) { case ParsingState.RowType: // This node tells us what kind of row we are reading. rowType = Convert.ToInt32(xmlNodeReader.Value); break; case ParsingState.LocalExecutionId: // The position type code is found in this cell. int localExecutionId = Convert.ToInt32(xmlNodeReader.Value); this.LocalMap.AddLocalMapRow(localExecutionId, documentVersion, rowIndex); break; case ParsingState.GlobalTicketId: // The position type code is found in this cell. int globalExecutionId = Convert.ToInt32(xmlNodeReader.Value); this.GlobalMap.AddGlobalMapRow(globalExecutionId, documentVersion, rowIndex); break; case ParsingState.Placeholder: // Keep track of where the placeholder is for new executions. this.placeholderRow = rowIndex; break; } // Reset the parsing state after each text node is read and interpreted. parsingState = ParsingState.None; break; } } // Commit all the changes made to the data set. this.AcceptChanges(); }