LinkedListNode <XmlUnit> BuildElemTree_SingleUnit( XmlElem InParent, LinkedListNode <XmlUnit> InSingleNode) { XmlUnit singleUnit = InSingleNode.Value; XmlElem singleElem = null; // create the XmlElem. Add to the parent. if (InParent == null) { singleElem = AddDocumentElem(); } else { singleElem = InParent.AddChild(); } singleElem.ElemName = singleUnit.UnitName; // the unit has named value properties. Store the named values as // child elements. if (singleUnit.SubUnits != null) { BuildElemTree_Attributes(singleElem, singleUnit); } return(InSingleNode); }
XmlUnit ScanValueUnit(int InBx) { Scanner.ScanCharResults res; XmlUnit unit = new XmlUnit(); unit.UnitCode = XmlUnitCode.Value; // unit value starts immed after prior open unit. ( whitespace is significant ) unit.Bx = InBx; // value runs until an xml bracket char. char[] braceChars = new char[] { '<', '>' }; res = Scanner.ScanEqualAny(mStream, unit.Bx, braceChars); if (res.ResultChar == '>') { throw new ApplicationException("xml close bracket not preceeded by open bracket"); } else if (res.ResultPos == -1) { unit.Ex = mStream.Length - 1; } else { unit.Ex = res.ResultPos - 1; } // store the unit value. if (unit.Bx != -1) { unit.UnitValue = DecodeXmlString(mStream.Substring(unit.Bx, unit.Ex - unit.Bx + 1)); } return(unit); }
/// <summary> /// an Infrastructure element is braced by <? .... ?> /// </summary> /// <param name="InBx"></param> /// <returns></returns> private XmlUnit CrackUnits_ScanInfrastructureUnit(int InBx) { XmlUnit unit = null; Scanner.ScanCharResults res; BoundedString boundedStream = new BoundedString(mStream); // scan for the end of the unit. ( there should be a > before an < ) res = Scanner.ScanEqualAny_BypassQuoted( boundedStream, InBx + 1, new char[] { '>', '<' }, QuoteEncapsulation.Double); if ((res.ResultPos == -1) || (res.ResultChar == '<')) { ThrowIncorrectlyFormedXmlException(InBx); } // "?" within the angle brackets. else if ((boundedStream[InBx + 1] != '?') || (boundedStream[res.ResultPos - 1] != '?')) { ThrowIncorrectlyFormedXmlException(InBx); } // setup the XmlUnit. else { unit = new XmlUnit(); unit.UnitCode = XmlUnitCode.InfraStructure; unit.Bx = InBx; unit.Ex = res.ResultPos; unit.UnitValue = boundedStream.Substring(unit.Bx, unit.Lx); } return(unit); }
void BuildElemTree_Attributes(XmlElem InParent, XmlUnit InParentUnit) { foreach (XmlUnit nmvUnit in InParentUnit.SubUnits) { XmlElem nmvElem = InParent.AddChild(); nmvElem.ElemName = nmvUnit.UnitName; nmvElem.ElemValue = nmvUnit.UnitValue; nmvElem.ValueForm = ValueForm.Attribute; } }
public string UnitToString(XmlUnit InUnit) { int bx = InUnit.Bx; int lx = InUnit.Lx; if (lx > 0) { return(mStream.Substring(bx, lx)); } else { return(""); } }
public XmlUnit AddAttribute( WordCursor InNameWord, WordCursor InEncodedAttributeValueWord) { if (mSubUnits == null) { mSubUnits = new List <XmlUnit>(); } XmlUnit AttributeUnit = new XmlUnit(); mSubUnits.Add(AttributeUnit); AttributeUnit.Bx = InNameWord.WordBx; AttributeUnit.Ex = InEncodedAttributeValueWord.WordEx; AttributeUnit.UnitCode = XmlUnitCode.Attribute; AttributeUnit.NameWord = InNameWord; AttributeUnit.EncodedAttributeValueWord = InEncodedAttributeValueWord; return(AttributeUnit); }
/// <summary> /// Build the Document element tree from the LinkedList of cracked /// document units. /// </summary> private void BuildDocumentElemTree() { LinkedListNode <XmlUnit> node = mUnits.First; while (node != null) { XmlUnit unit = node.Value; if (unit.UnitCode == XmlUnitCode.InfraStructure) { } else if (unit.UnitCode == XmlUnitCode.Single) { if (mDocElem != null) { ThrowIncorrectlyFormedXmlException( "document has more than one root element", unit); } else { node = BuildElemTree_SingleUnit(null, node); } } else if (unit.UnitCode == XmlUnitCode.Open) { if (mDocElem != null) { ThrowIncorrectlyFormedXmlException( "document has more than one root element", unit); } else { node = BuildElemTree_OpenUnit(null, node); } } else { ThrowIncorrectlyFormedXmlException("Incorrectly placed xml unit", unit); } node = node.Next; } }
void CrackUnits() { XmlUnit curUnit = null; XmlUnit nxUnit = null; while (true) { curUnit = nxUnit; nxUnit = CrackUnits_CrackNext(curUnit); if (nxUnit == null) { break; } if (curUnit != null) { curUnit.NextUnit = nxUnit; } mUnits.AddLast(nxUnit); } }
static void ThrowIncorrectlyFormedXmlException( string InText, XmlUnit InUnit) { throw new ApplicationException( "Incorrectly formed XML. " + InText); }
XmlUnit CrackUnits_ScanOpenUnit(int InBx) { Scanner.ScanCharResults res; XmlUnit unit = new XmlUnit(); unit.UnitCode = XmlUnitCode.Open; WordCursor nxWord = null; BoundedString boundedStream = new BoundedString(mStream); // unit starts with "<" if (boundedStream[InBx] != '<') { ThrowIncorrectlyFormedXmlException(InBx); } unit.Bx = InBx; // scan for the end of the unit. ( there should be a > before an < ) res = Scanner.ScanEqualAny_BypassQuoted( boundedStream, InBx + 1, new char[] { '>', '<' }, QuoteEncapsulation.Double); if ((res.ResultPos == -1) || (res.ResultChar == '<')) { ThrowIncorrectlyFormedXmlException(InBx); } else { unit.Ex = res.ResultPos; } // setup to step from word to word in the unit. boundedStream = new BoundedString(mStream, InBx + 1, res.ResultPos - 1); TextTraits traits = new TextTraits(); traits.OpenNamedBracedPatterns.Clear( ); traits.DividerPatterns.Add("/", "=", DelimClassification.DividerSymbol); traits.WhitespacePatterns.AddDistinct( Environment.NewLine, DelimClassification.Whitespace); // isolate the words of the open unit. WordCursor csr = Scanner.ScanFirstWord(boundedStream, traits); while (true) { if (csr.IsEndOfString == true) { break; } // the unit name if (ScanOpenUnit_CursorAtUnitName(csr) == true) { if (unit.NameWord != null) { ThrowIncorrectlyFormedXmlException(InBx); // already have a unit name } else { unit.NameWord = csr; } } // no word. just the ending "/". ( handle a little later. ) else if ((csr.Word == null) && (csr.DelimValue == "/")) { } else if (csr.Word == null) { ThrowIncorrectlyFormedXmlException(InBx); } // handle as an element attribute ( a named value pair ) else { nxWord = ScanOpenUnit_Attribute_GetValue(boundedStream, csr); if (nxWord != null) { // note: attributes values are stored in their xml encoded // state. unit.AddAttribute(csr, nxWord); csr = nxWord; } else { ThrowIncorrectlyFormedXmlException(InBx); } } // process the "/" delimeter. ( must be the end of the OpenUnit ) if (csr.DelimValue == "/") { WordCursor nx = Scanner.ScanNextWord(boundedStream, csr); if (nx.IsEndOfString == true) { unit.UnitCode = XmlUnitCode.Single; break; } else { ThrowIncorrectlyFormedXmlException(InBx); } } csr = Scanner.ScanNextWord(boundedStream, csr); } return(unit); }
private XmlUnit CrackUnits_ScanCloseUnit(int InBx) { Scanner.ScanCharResults res; XmlUnit unit = new XmlUnit(); unit.UnitCode = XmlUnitCode.Close; WordCursor csr = null; BoundedString boundedStream = new BoundedString(mStream); // unit starts with "<" if (boundedStream[InBx] != '<') { ThrowIncorrectlyFormedXmlException(InBx); } unit.Bx = InBx; // scan for the end of the unit. ( there should be a > before an < ) res = Scanner.ScanEqualAny_BypassQuoted( boundedStream, InBx + 1, new char[] { '>', '<' }, QuoteEncapsulation.Double); if ((res.ResultPos == -1) || (res.ResultChar == '<')) { ThrowIncorrectlyFormedXmlException(InBx); } else { unit.Ex = res.ResultPos; } // setup to step from word to word in the close unit. boundedStream = new BoundedString(mStream, InBx + 1, res.ResultPos - 1); TextTraits traits = new TextTraits(); traits.OpenNamedBracedPatterns.Clear(); traits.DividerPatterns.Add("/", "=", DelimClassification.DividerSymbol); // first word must be an empty word w/ "/" delim. csr = Scanner.ScanFirstWord(boundedStream, traits); if ((csr.IsDelimOnly) && (csr.DelimValue == "/")) { } else { ThrowIncorrectlyFormedXmlException(InBx); } // next is a name with end of string delim. csr = Scanner.ScanNextWord(boundedStream, csr); if ((csr.IsEndOfString) || (csr.DelimClass == DelimClassification.EndOfString)) { } else { ThrowIncorrectlyFormedXmlException(InBx); } // if there is an element name, store it. if (csr.Word != null) { unit.NameWord = csr; } return(unit); }
XmlUnit CrackUnits_CrackNext(XmlUnit InCurUnit) { int ix; int vluBx; XmlUnit unit = null; // calc scan start point if (InCurUnit == null) { ix = 0; } else if (InCurUnit.UnitCode == XmlUnitCode.None) { ix = 0; } else { ix = InCurUnit.Bx + InCurUnit.Lx; } // advance past whitespace vluBx = ix; int streamEx = mStream.Length - 1; ScanPatternResults res = Scanner.ScanNotEqual( mStream, ix, streamEx, mTraits.WhitespacePatterns); ix = res.FoundPos; // end of stream. if (ix == -1) { unit = null; } // some sort of open or close unit. else if (res.FoundChar.Value == '<') { Nullable <char> nxChar = Scanner.ScanNotEqual( mStream, ix + 1, streamEx, mTraits.WhitespacePatterns).FoundChar; // starting an xml close unit </name> if ((nxChar != null) && (nxChar.Value == '/')) { unit = CrackUnits_ScanCloseUnit(res.FoundPos); } // a document infrastructure unit <? ...... ?> else if ((nxChar != null) && (nxChar.Value == '?')) { unit = CrackUnits_ScanInfrastructureUnit(res.FoundPos); } // starting an xml open unit <name xxxxxx> else { unit = CrackUnits_ScanOpenUnit(res.FoundPos); } } // a value unit is the xml text between the open and close unit. else { unit = ScanValueUnit(vluBx); } return(unit); }
/// <summary> /// Build a branch in the XmlElem tree from an open XmlUnit. /// </summary> /// <param name="InParent"></param> /// <param name="InOpenNode"></param> /// <returns></returns> LinkedListNode <XmlUnit> BuildElemTree_OpenUnit( XmlElem InParent, LinkedListNode <XmlUnit> InOpenNode) { XmlElem openElem = null; XmlUnit openUnit = InOpenNode.Value; LinkedListNode <XmlUnit> closeUnitNode = null; // create the XmlElem. Add to the parent. if (InParent == null) { openElem = AddDocumentElem(); } else { openElem = InParent.AddChild(); } openElem.ElemName = openUnit.UnitName; // the unit has named value properties. Store the named values as // child elements. if (openUnit.SubUnits != null) { BuildElemTree_Attributes(openElem, openUnit); } // step from unit to unit until the close unit. LinkedListNode <XmlUnit> curNode = InOpenNode; while (true) { curNode = curNode.Next; if (curNode == null) { ThrowIncorrectlyFormedXmlException("Close unit of open unit not found", openUnit); } // process the unit according to its UnitCode. XmlUnit unit = curNode.Value; // the value of the open unit. if (unit.UnitCode == XmlUnitCode.Value) { if (openElem.ElemValue != null) { ThrowIncorrectlyFormedXmlException("xml element already has a value", openUnit); } openElem.ElemValue = unit.UnitValue; openElem.ValueForm = ValueForm.OpenCloseBraced; } // the close unit. else if (unit.UnitCode == XmlUnitCode.Close) { if ((unit.UnitName != null) && (unit.UnitName != openElem.ElemName)) { ThrowIncorrectlyFormedXmlException("Close unit name does not match open unit", openUnit); } else { closeUnitNode = curNode; break; } } // a single unit. process as a sub element of this open unit element. else if (unit.UnitCode == XmlUnitCode.Single) { curNode = BuildElemTree_SingleUnit(openElem, curNode); } // an open unit within this open unit. process as a sub element. else if (unit.UnitCode == XmlUnitCode.Open) { curNode = BuildElemTree_OpenUnit(openElem, curNode); } // any other kind of XmlUnit is an error. else { ThrowIncorrectlyFormedXmlException("Unexpected XmlUnit", openUnit); } } return(closeUnitNode); }