private void FormatAttribute(System.Xml.XmlWriter writer, IStream <Token <MarkupTokenType> > stream) { Token <MarkupTokenType> token = stream.Peek(); writer.WriteStartAttribute(token.Name.Prefix, token.Name.LocalName, token.Name.NamespaceUri); stream.Pop(); token = stream.Peek(); switch (token.TokenType) { case MarkupTokenType.Primitive: { ITextFormattable <MarkupTokenType> formattable = token.Value as ITextFormattable <MarkupTokenType>; if (formattable != null) { formattable.Format(this, new XmlWriterAdapter(writer)); } else { writer.WriteString(token.ValueAsString()); } break; } default: { throw new TokenException <MarkupTokenType>( token, String.Format(ErrorUnexpectedToken, token)); } } stream.Pop(); writer.WriteEndAttribute(); }
private void WriteAttribute(TextWriter writer, string prefix, string localName, Token <MarkupTokenType> value) { // " " writer.Write(MarkupGrammar.OperatorValueDelim); if (!String.IsNullOrEmpty(prefix)) { // "prefix:" this.WriteLocalName(writer, prefix); writer.Write(MarkupGrammar.OperatorPrefixDelim); } // local-name this.WriteLocalName(writer, localName); ITextFormattable <MarkupTokenType> formattable = value.Value as ITextFormattable <MarkupTokenType>; string attrValue = (formattable == null) ? value.ValueAsString() : null; if ((formattable == null) && String.IsNullOrEmpty(attrValue)) { switch (this.EmptyAttributes) { case EmptyAttributeType.Html: { return; } case EmptyAttributeType.Xhtml: { attrValue = localName; break; } case EmptyAttributeType.Xml: { break; } } } // ="value" writer.Write(MarkupGrammar.OperatorPairDelim); writer.Write(MarkupGrammar.OperatorStringDelim); switch (value.TokenType) { case MarkupTokenType.Primitive: { if (formattable != null) { formattable.Format(this, writer); } else { HtmlFormatter.HtmlAttributeEncode(writer, attrValue, this.encodeNonAscii, this.canonicalForm); } break; } default: { throw new TokenException <MarkupTokenType>( value, String.Format(HtmlFormatter.ErrorUnexpectedToken, value)); } } writer.Write(MarkupGrammar.OperatorStringDelim); }
/// <summary> /// Formats the token sequence to the writer /// </summary> /// <param name="writer"></param> /// <param name="tokens"></param> public void Format(IEnumerable <Token <MarkupTokenType> > tokens, TextWriter writer) { if (tokens == null) { throw new ArgumentNullException("tokens"); } IStream <Token <MarkupTokenType> > stream = Stream <Token <MarkupTokenType> > .Create(tokens); PrefixScopeChain.Scope scope = null; while (!stream.IsCompleted) { Token <MarkupTokenType> token = stream.Peek(); switch (token.TokenType) { case MarkupTokenType.ElementBegin: case MarkupTokenType.ElementVoid: { DataName tagName = token.Name; MarkupTokenType tagType = token.TokenType; stream.Pop(); token = stream.Peek(); scope = new PrefixScopeChain.Scope(); if (this.ScopeChain.ContainsNamespace(tagName.NamespaceUri) || (String.IsNullOrEmpty(tagName.NamespaceUri) && !this.ScopeChain.ContainsPrefix(String.Empty))) { string prefix = this.ScopeChain.GetPrefix(tagName.NamespaceUri, false); scope.TagName = new DataName(tagName.LocalName, prefix, tagName.NamespaceUri); } else { scope[tagName.Prefix] = tagName.NamespaceUri; scope.TagName = tagName; } this.ScopeChain.Push(scope); IDictionary <DataName, Token <MarkupTokenType> > attributes = null; while (!stream.IsCompleted && token.TokenType == MarkupTokenType.Attribute) { if (attributes == null) { attributes = this.canonicalForm ? (IDictionary <DataName, Token <MarkupTokenType> >) new CanonicalList() : (IDictionary <DataName, Token <MarkupTokenType> >) new Dictionary <DataName, Token <MarkupTokenType> >(); } DataName attrName = token.Name; string prefix = this.ScopeChain.EnsurePrefix(attrName.Prefix, attrName.NamespaceUri); if (prefix != null) { if (prefix != attrName.Prefix) { attrName = new DataName(attrName.LocalName, prefix, attrName.NamespaceUri, true); } if (!this.ScopeChain.ContainsNamespace(attrName.NamespaceUri) && (!String.IsNullOrEmpty(attrName.NamespaceUri) || this.ScopeChain.ContainsPrefix(String.Empty))) { scope[prefix] = attrName.NamespaceUri; } } stream.Pop(); token = stream.Peek(); attributes[attrName] = token ?? MarkupGrammar.TokenNone; stream.Pop(); token = stream.Peek(); } this.WriteTag(writer, tagType, tagName, attributes, scope); scope = null; break; } case MarkupTokenType.ElementEnd: { if (this.ScopeChain.HasScope) { this.WriteTag(writer, MarkupTokenType.ElementEnd, this.ScopeChain.Peek().TagName, null, null); this.ScopeChain.Pop(); } else { // TODO: decide if this is should throw an exception } stream.Pop(); token = stream.Peek(); break; } case MarkupTokenType.Primitive: { ITextFormattable <MarkupTokenType> formattable = token.Value as ITextFormattable <MarkupTokenType>; if (formattable != null) { formattable.Format(this, writer); } else { HtmlFormatter.HtmlEncode(writer, token.ValueAsString(), this.encodeNonAscii, this.canonicalForm); } stream.Pop(); token = stream.Peek(); break; } default: { throw new TokenException <MarkupTokenType>( token, String.Format(ErrorUnexpectedToken, token.TokenType)); } } } }
/// <summary> /// Formats the token sequence to the writer /// </summary> /// <param name="writer"></param> /// <param name="tokens"></param> public void Format(IEnumerable <Token <ModelTokenType> > tokens, TextWriter writer) { if (tokens == null) { throw new ArgumentNullException("tokens"); } bool prettyPrint = this.Settings.PrettyPrint; // allows us to keep basic context without resorting to a push-down automata bool pendingNewLine = false; bool needsValueDelim = false; int depth = 0; foreach (Token <ModelTokenType> token in tokens) { switch (token.TokenType) { case ModelTokenType.ArrayBegin: { if (needsValueDelim) { writer.Write(JsonGrammar.OperatorValueDelim); if (prettyPrint) { this.WriteLine(writer, depth); } } if (pendingNewLine) { if (prettyPrint) { this.WriteLine(writer, ++depth); } pendingNewLine = false; } writer.Write(JsonGrammar.OperatorArrayBegin); pendingNewLine = true; needsValueDelim = false; continue; } case ModelTokenType.ArrayEnd: { if (pendingNewLine) { pendingNewLine = false; } else if (prettyPrint) { this.WriteLine(writer, --depth); } writer.Write(JsonGrammar.OperatorArrayEnd); needsValueDelim = true; continue; } case ModelTokenType.Primitive: { if (needsValueDelim) { writer.Write(JsonGrammar.OperatorValueDelim); if (prettyPrint) { this.WriteLine(writer, depth); } } if (pendingNewLine) { if (prettyPrint) { this.WriteLine(writer, ++depth); } pendingNewLine = false; } Type valueType = (token.Value == null) ? null : token.Value.GetType(); TypeCode typeCode = Type.GetTypeCode(valueType); switch (typeCode) { case TypeCode.Boolean: { writer.Write(true.Equals(token.Value) ? JsonGrammar.KeywordTrue : JsonGrammar.KeywordFalse); break; } case TypeCode.Byte: case TypeCode.Decimal: case TypeCode.Double: case TypeCode.Int16: case TypeCode.Int32: case TypeCode.Int64: case TypeCode.SByte: case TypeCode.Single: case TypeCode.UInt16: case TypeCode.UInt32: case TypeCode.UInt64: { if (valueType.IsEnum) { goto default; } this.WriteNumber(writer, token.Value, typeCode); break; } case TypeCode.DBNull: case TypeCode.Empty: { writer.Write(JsonGrammar.KeywordNull); break; } default: { ITextFormattable <ModelTokenType> formattable = token.Value as ITextFormattable <ModelTokenType>; if (formattable != null) { formattable.Format(this, writer); break; } this.WritePrimitive(writer, token.Value); break; } } needsValueDelim = true; continue; } case ModelTokenType.ObjectBegin: { if (needsValueDelim) { writer.Write(JsonGrammar.OperatorValueDelim); if (prettyPrint) { this.WriteLine(writer, depth); } } if (pendingNewLine) { if (prettyPrint) { this.WriteLine(writer, ++depth); } pendingNewLine = false; } writer.Write(JsonGrammar.OperatorObjectBegin); pendingNewLine = true; needsValueDelim = false; continue; } case ModelTokenType.ObjectEnd: { if (pendingNewLine) { pendingNewLine = false; } else if (prettyPrint) { this.WriteLine(writer, --depth); } writer.Write(JsonGrammar.OperatorObjectEnd); needsValueDelim = true; continue; } case ModelTokenType.Property: { if (needsValueDelim) { writer.Write(JsonGrammar.OperatorValueDelim); if (prettyPrint) { this.WriteLine(writer, depth); } } if (pendingNewLine) { if (prettyPrint) { this.WriteLine(writer, ++depth); } pendingNewLine = false; } this.WritePropertyName(writer, token.Name.LocalName); if (prettyPrint) { writer.Write(" "); writer.Write(JsonGrammar.OperatorPairDelim); writer.Write(" "); } else { writer.Write(JsonGrammar.OperatorPairDelim); } needsValueDelim = false; continue; } case ModelTokenType.None: default: { throw new TokenException <ModelTokenType>( token, String.Format(ErrorUnexpectedToken, token.TokenType)); } } } }
/// <summary> /// Formats the token sequence to the writer /// </summary> /// <param name="writer"></param> /// <param name="tokens"></param> public void Format(System.Xml.XmlWriter writer, IEnumerable <Token <MarkupTokenType> > tokens) { if (writer == null) { throw new ArgumentNullException("writer"); } if (tokens == null) { throw new ArgumentNullException("tokens"); } int depth = 0; IStream <Token <MarkupTokenType> > stream = Stream <Token <MarkupTokenType> > .Create(tokens); Token <MarkupTokenType> token = stream.Peek(); try { while (!stream.IsCompleted) { switch (token.TokenType) { case MarkupTokenType.ElementBegin: { depth++; writer.WriteStartElement(token.Name.Prefix, token.Name.LocalName, token.Name.NamespaceUri); stream.Pop(); token = stream.Peek(); break; } case MarkupTokenType.ElementVoid: { writer.WriteStartElement(token.Name.Prefix, token.Name.LocalName, token.Name.NamespaceUri); stream.Pop(); token = stream.Peek(); while (!stream.IsCompleted && token.TokenType == MarkupTokenType.Attribute) { this.FormatAttribute(writer, stream); token = stream.Peek(); } writer.WriteEndElement(); break; } case MarkupTokenType.ElementEnd: { depth--; writer.WriteEndElement(); stream.Pop(); token = stream.Peek(); break; } case MarkupTokenType.Attribute: { this.FormatAttribute(writer, stream); token = stream.Peek(); break; } case MarkupTokenType.Primitive: { ITextFormattable <MarkupTokenType> formattable = token.Value as ITextFormattable <MarkupTokenType>; if (formattable != null) { formattable.Format(this, new XmlWriterAdapter(writer)); } else { writer.WriteString(token.ValueAsString()); } stream.Pop(); token = stream.Peek(); break; } default: { throw new TokenException <MarkupTokenType>( token, String.Format(ErrorUnexpectedToken, token.TokenType)); } } } while (depth-- > 0) { // auto close otherwise XmlWriter will choke writer.WriteEndElement(); } } catch (Exception ex) { throw new TokenException <MarkupTokenType>(token, ex.Message, ex); } }