You've already forked linux-packaging-mono
Imported Upstream version 4.6.0.125
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
This commit is contained in:
parent
a569aebcfd
commit
e79aa3c0ed
@@ -0,0 +1,49 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="BaseTreeIterator.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// <owner current="true" primary="true">[....]</owner>
|
||||
// <owner current="true" primary="false">[....]</owner>
|
||||
//------------------------------------------------------------------------------
|
||||
namespace System.Xml {
|
||||
|
||||
// Iterates over non-attribute nodes
|
||||
internal abstract class BaseTreeIterator {
|
||||
protected DataSetMapper mapper;
|
||||
|
||||
internal BaseTreeIterator( DataSetMapper mapper ) {
|
||||
this.mapper = mapper;
|
||||
}
|
||||
|
||||
internal abstract void Reset();
|
||||
|
||||
internal abstract XmlNode CurrentNode { get; }
|
||||
|
||||
internal abstract bool Next();
|
||||
internal abstract bool NextRight();
|
||||
|
||||
internal bool NextRowElement() {
|
||||
while ( Next() ) {
|
||||
if ( OnRowElement() )
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
internal bool NextRightRowElement() {
|
||||
if ( NextRight() ) {
|
||||
if ( OnRowElement() )
|
||||
return true;
|
||||
return NextRowElement();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Returns true if the current node is on a row element (head of a region)
|
||||
internal bool OnRowElement() {
|
||||
XmlBoundElement be = CurrentNode as XmlBoundElement;
|
||||
return (be != null) && (be.Row != null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,202 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="DataDocumentXPathNavigator.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// <owner current="true" primary="true">[....]</owner>
|
||||
// <owner current="true" primary="false">[....]</owner>
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma warning disable 618 // ignore obsolete warning about XmlDataDocument
|
||||
namespace System.Xml {
|
||||
using System;
|
||||
using System.Xml.XPath;
|
||||
|
||||
internal sealed class DataDocumentXPathNavigator: XPathNavigator, IHasXmlNode {
|
||||
private XPathNodePointer _curNode; //pointer to remember the current node position
|
||||
private XmlDataDocument _doc; //pointer to remember the root -- can only be XmlDataDocument for DataDocumentXPathNavigator
|
||||
private XPathNodePointer _temp;
|
||||
|
||||
internal DataDocumentXPathNavigator( XmlDataDocument doc, XmlNode node ) {
|
||||
_curNode = new XPathNodePointer( this, doc, node );
|
||||
_temp = new XPathNodePointer( this, doc, node );
|
||||
_doc = doc;
|
||||
}
|
||||
|
||||
private DataDocumentXPathNavigator( DataDocumentXPathNavigator other ) {
|
||||
this._curNode = other._curNode.Clone( this );
|
||||
this._temp = other._temp.Clone( this );
|
||||
this._doc = other._doc;
|
||||
}
|
||||
public override XPathNavigator Clone(){
|
||||
return new DataDocumentXPathNavigator( this );
|
||||
}
|
||||
|
||||
internal XPathNodePointer CurNode { get { return _curNode; } }
|
||||
internal XmlDataDocument Document { get { return _doc; } }
|
||||
|
||||
//Convert will deal with nodeType as Attribute or Namespace nodes
|
||||
public override XPathNodeType NodeType { get { return _curNode.NodeType; } }
|
||||
|
||||
public override string LocalName { get { return _curNode.LocalName; } }
|
||||
|
||||
public override string NamespaceURI { get { return _curNode.NamespaceURI; } }
|
||||
|
||||
public override string Name { get { return _curNode.Name; } }
|
||||
|
||||
public override string Prefix { get { return _curNode.Prefix; } }
|
||||
|
||||
public override string Value {
|
||||
get {
|
||||
XPathNodeType xnt = _curNode.NodeType;
|
||||
if ( xnt == XPathNodeType.Element || xnt == XPathNodeType.Root )
|
||||
return _curNode.InnerText;
|
||||
return _curNode.Value;
|
||||
}
|
||||
}
|
||||
|
||||
public override String BaseURI { get { return _curNode.BaseURI; } }
|
||||
|
||||
public override String XmlLang { get { return _curNode.XmlLang; } }
|
||||
|
||||
public override bool IsEmptyElement { get { return _curNode.IsEmptyElement; } }
|
||||
|
||||
public override XmlNameTable NameTable { get { return _doc.NameTable; } }
|
||||
|
||||
// Attributes
|
||||
public override bool HasAttributes { get { return _curNode.AttributeCount > 0; } }
|
||||
|
||||
public override string GetAttribute( string localName, string namespaceURI ) {
|
||||
if ( _curNode.NodeType != XPathNodeType.Element )
|
||||
return string.Empty; //other type of nodes can't have attributes
|
||||
_temp.MoveTo( _curNode );
|
||||
if ( _temp.MoveToAttribute( localName, namespaceURI ) )
|
||||
return _temp.Value;
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
//#if SupportNamespaces
|
||||
|
||||
public override string GetNamespace(string name) {
|
||||
return _curNode.GetNamespace( name );
|
||||
}
|
||||
|
||||
public override bool MoveToNamespace(string name) {
|
||||
if ( _curNode.NodeType != XPathNodeType.Element )
|
||||
return false;
|
||||
return _curNode.MoveToNamespace( name );
|
||||
}
|
||||
|
||||
public override bool MoveToFirstNamespace(XPathNamespaceScope namespaceScope) {
|
||||
if ( _curNode.NodeType != XPathNodeType.Element )
|
||||
return false;
|
||||
return _curNode.MoveToFirstNamespace(namespaceScope);
|
||||
}
|
||||
|
||||
public override bool MoveToNextNamespace(XPathNamespaceScope namespaceScope) {
|
||||
if ( _curNode.NodeType != XPathNodeType.Namespace )
|
||||
return false;
|
||||
return _curNode.MoveToNextNamespace(namespaceScope);
|
||||
}
|
||||
//#endif
|
||||
|
||||
public override bool MoveToAttribute( string localName, string namespaceURI ) {
|
||||
if ( _curNode.NodeType != XPathNodeType.Element )
|
||||
return false; //other type of nodes can't have attributes
|
||||
return _curNode.MoveToAttribute( localName, namespaceURI );
|
||||
}
|
||||
|
||||
public override bool MoveToFirstAttribute() {
|
||||
if ( _curNode.NodeType != XPathNodeType.Element )
|
||||
return false; //other type of nodes can't have attributes
|
||||
return _curNode.MoveToNextAttribute(true);
|
||||
}
|
||||
|
||||
public override bool MoveToNextAttribute() {
|
||||
if ( _curNode.NodeType != XPathNodeType.Attribute )
|
||||
return false;
|
||||
return _curNode.MoveToNextAttribute(false);
|
||||
}
|
||||
|
||||
|
||||
// Tree
|
||||
public override bool MoveToNext() {
|
||||
if ( _curNode.NodeType == XPathNodeType.Attribute )
|
||||
return false;
|
||||
return _curNode.MoveToNextSibling();
|
||||
}
|
||||
|
||||
public override bool MoveToPrevious() {
|
||||
if ( _curNode.NodeType == XPathNodeType.Attribute )
|
||||
return false;
|
||||
return _curNode.MoveToPreviousSibling();
|
||||
}
|
||||
|
||||
public override bool MoveToFirst() {
|
||||
if ( _curNode.NodeType == XPathNodeType.Attribute )
|
||||
return false;
|
||||
return _curNode.MoveToFirst();
|
||||
}
|
||||
|
||||
public override bool HasChildren { get { return _curNode.HasChildren; } }
|
||||
|
||||
public override bool MoveToFirstChild() {
|
||||
return _curNode.MoveToFirstChild();
|
||||
}
|
||||
|
||||
public override bool MoveToParent() {
|
||||
return _curNode.MoveToParent();
|
||||
}
|
||||
|
||||
public override void MoveToRoot() {
|
||||
_curNode.MoveToRoot();
|
||||
}
|
||||
|
||||
public override bool MoveTo( XPathNavigator other ) {
|
||||
if ( other == null )
|
||||
return false;
|
||||
DataDocumentXPathNavigator otherDataDocXPathNav = other as DataDocumentXPathNavigator;
|
||||
if ( otherDataDocXPathNav != null ) {
|
||||
if ( _curNode.MoveTo( otherDataDocXPathNav.CurNode ) ) {
|
||||
_doc = _curNode.Document;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//doesn't support MoveToId
|
||||
public override bool MoveToId( string id ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool IsSamePosition( XPathNavigator other ) {
|
||||
if ( other == null )
|
||||
return false;
|
||||
DataDocumentXPathNavigator otherDataDocXPathNav = other as DataDocumentXPathNavigator;
|
||||
if ( otherDataDocXPathNav != null ) {
|
||||
if ( this._doc == otherDataDocXPathNav.Document && this._curNode.IsSamePosition(otherDataDocXPathNav.CurNode) )
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//the function is only called for XPathNodeList enumerate nodes and
|
||||
// shouldn't be promoted to frequently use because it will cause foliation
|
||||
XmlNode IHasXmlNode.GetNode() { return _curNode.Node; }
|
||||
|
||||
public override XmlNodeOrder ComparePosition( XPathNavigator other ) {
|
||||
if ( other == null )
|
||||
return XmlNodeOrder.Unknown; // this is what XPathDocument does. // WebData 103403
|
||||
|
||||
DataDocumentXPathNavigator otherDataDocXPathNav = other as DataDocumentXPathNavigator;
|
||||
|
||||
if ( otherDataDocXPathNav == null || otherDataDocXPathNav.Document != this._doc )
|
||||
return XmlNodeOrder.Unknown;
|
||||
|
||||
return this._curNode.ComparePosition( otherDataDocXPathNav.CurNode );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,350 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="DataSetMapper.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// <owner current="true" primary="true">[....]</owner>
|
||||
// <owner current="true" primary="false">[....]</owner>
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma warning disable 618 // ignore obsolete warning about XmlDataDocument
|
||||
namespace System.Xml {
|
||||
|
||||
using System.Collections;
|
||||
using System.Data;
|
||||
using System.Diagnostics;
|
||||
|
||||
|
||||
//
|
||||
// Maps XML nodes to schema
|
||||
//
|
||||
// With the exception of some functions (the most important is SearchMatchingTableSchema) all functions expect that each region rowElem is already associated
|
||||
// w/ it's DataRow (basically the test to determine a rowElem is based on a != null associated DataRow). As a result of this, some functions will NOT work properly
|
||||
// when they are used on a tree for which rowElem's are not associated w/ a DataRow.
|
||||
//
|
||||
|
||||
internal sealed class DataSetMapper {
|
||||
Hashtable tableSchemaMap; // maps an string (currently this is localName:nsURI) to a DataTable. Used to quickly find if a bound-elem matches any data-table metadata..
|
||||
Hashtable columnSchemaMap; // maps a string (table localName:nsURI) to a Hashtable. The 2nd hastable (the one that is stored as data in columnSchemaMap, maps a string to a DataColumn.
|
||||
|
||||
XmlDataDocument doc; // The document this mapper is related to
|
||||
DataSet dataSet; // The dataset this mapper is related to
|
||||
internal const string strReservedXmlns = "http://www.w3.org/2000/xmlns/";
|
||||
|
||||
|
||||
internal DataSetMapper() {
|
||||
Debug.Assert( this.dataSet == null );
|
||||
this.tableSchemaMap = new Hashtable();
|
||||
this.columnSchemaMap = new Hashtable();
|
||||
}
|
||||
|
||||
internal void SetupMapping( XmlDataDocument xd, DataSet ds ) {
|
||||
// If are already mapped, forget about our current mapping and re-do it again.
|
||||
if ( IsMapped() ) {
|
||||
this.tableSchemaMap = new Hashtable();
|
||||
this.columnSchemaMap = new Hashtable();
|
||||
}
|
||||
doc = xd;
|
||||
dataSet = ds;
|
||||
foreach( DataTable t in dataSet.Tables ) {
|
||||
AddTableSchema( t );
|
||||
|
||||
foreach( DataColumn c in t.Columns ) {
|
||||
// don't include auto-generated PK & FK to be part of mapping
|
||||
if ( ! IsNotMapped(c) ) {
|
||||
AddColumnSchema( c );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal bool IsMapped() {
|
||||
return dataSet != null;
|
||||
}
|
||||
|
||||
internal DataTable SearchMatchingTableSchema( string localName, string namespaceURI ) {
|
||||
object tid = GetIdentity( localName, namespaceURI );
|
||||
return (DataTable)(tableSchemaMap[ tid ]);
|
||||
|
||||
}
|
||||
// SearchMatchingTableSchema function works only when the elem has not been bound to a DataRow. If you want to get the table associated w/ an element after
|
||||
// it has been associated w/ a DataRow use GetTableSchemaForElement function.
|
||||
// rowElem is the parent region rowElem or null if there is no parent region (in case elem is a row elem, then rowElem will be the parent region; if elem is not
|
||||
// mapped to a DataRow, then rowElem is the region elem is part of)
|
||||
//
|
||||
// Those are the rules for determing if elem is a row element:
|
||||
// 1. node is an element (already meet, since elem is of type XmlElement)
|
||||
// 2. If the node is already associated w/ a DataRow, then the node is a row element - not applicable, b/c this function is intended to be called on a
|
||||
// to find out if the node s/b associated w/ a DataRow (see XmlDataDocument.LoadRows)
|
||||
// 3. If the node localName/ns matches a DataTable then
|
||||
// 3.1 Take the parent region DataTable (in our case rowElem.Row.DataTable)
|
||||
// 3.2 If no parent region, then the node is associated w/ a DataTable
|
||||
// 3.3 If there is a parent region
|
||||
// 3.3.1 If the node has no elem children and no attr other than namespace declaration, and the node can match
|
||||
// a column from the parent region table, then the node is NOT associated w/ a DataTable (it is a potential DataColumn in the parent region)
|
||||
// 3.3.2 Else the node is a row-element (and associated w/ a DataTable / DataRow )
|
||||
//
|
||||
internal DataTable SearchMatchingTableSchema( XmlBoundElement rowElem, XmlBoundElement elem ) {
|
||||
Debug.Assert( elem != null );
|
||||
|
||||
DataTable t = SearchMatchingTableSchema( elem.LocalName, elem.NamespaceURI );
|
||||
if ( t == null )
|
||||
return null;
|
||||
|
||||
if ( rowElem == null )
|
||||
return t;
|
||||
// Currently we expect we map things from top of the tree to the bottom
|
||||
Debug.Assert( rowElem.Row != null );
|
||||
|
||||
DataColumn col = GetColumnSchemaForNode( rowElem, elem );
|
||||
if ( col == null )
|
||||
return t;
|
||||
|
||||
foreach ( XmlAttribute a in elem.Attributes ) {
|
||||
#if DEBUG
|
||||
// Some sanity check to catch errors like namespace attributes have the right localName/namespace value, but a wrong atomized namespace value
|
||||
if ( a.LocalName == "xmlns" ) {
|
||||
Debug.Assert( a.Prefix != null && a.Prefix.Length == 0 );
|
||||
Debug.Assert( (object)a.NamespaceURI == (object)strReservedXmlns );
|
||||
}
|
||||
if ( a.Prefix == "xmlns" ) {
|
||||
Debug.Assert( (object)a.NamespaceURI == (object)strReservedXmlns );
|
||||
}
|
||||
if ( a.NamespaceURI == strReservedXmlns )
|
||||
Debug.Assert( (object)a.NamespaceURI == (object)strReservedXmlns );
|
||||
#endif
|
||||
// No namespace attribute found, so elem cannot be a potential DataColumn, therefore is a row-elem
|
||||
if ( (object)(a.NamespaceURI) != (object)strReservedXmlns )
|
||||
return t;
|
||||
}
|
||||
|
||||
for ( XmlNode n = elem.FirstChild; n != null; n = n.NextSibling ) {
|
||||
if ( n.NodeType == XmlNodeType.Element ) {
|
||||
// elem has an element child, so elem cannot be a potential DataColumn, therefore is a row-elem
|
||||
return t;
|
||||
}
|
||||
}
|
||||
// Node is a potential DataColumn in rowElem region
|
||||
return null;
|
||||
}
|
||||
|
||||
internal DataColumn GetColumnSchemaForNode( XmlBoundElement rowElem, XmlNode node ) {
|
||||
//
|
||||
Debug.Assert( rowElem != null );
|
||||
// The caller must make sure that node is not a row-element
|
||||
Debug.Assert( (node is XmlBoundElement) ? ((XmlBoundElement)node).Row == null : true );
|
||||
|
||||
object tid = GetIdentity( rowElem.LocalName, rowElem.NamespaceURI );
|
||||
object cid = GetIdentity( node.LocalName, node.NamespaceURI );
|
||||
|
||||
Hashtable columns = (Hashtable) columnSchemaMap[ tid ];
|
||||
if ( columns != null ) {
|
||||
DataColumn col = (DataColumn)(columns[ cid ]);
|
||||
if ( col == null )
|
||||
return null;
|
||||
|
||||
MappingType mt = col.ColumnMapping;
|
||||
|
||||
if ( node.NodeType == XmlNodeType.Attribute && mt == MappingType.Attribute )
|
||||
return col;
|
||||
if ( node.NodeType == XmlNodeType.Element && mt == MappingType.Element )
|
||||
return col;
|
||||
// node's (localName, ns) matches a column, but the MappingType is different (i.e. node is elem, MT is attr)
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
internal DataTable GetTableSchemaForElement( XmlElement elem ) {
|
||||
//
|
||||
XmlBoundElement be = elem as XmlBoundElement;
|
||||
if ( be == null )
|
||||
return null;
|
||||
|
||||
return GetTableSchemaForElement( be );
|
||||
}
|
||||
|
||||
internal DataTable GetTableSchemaForElement( XmlBoundElement be ) {
|
||||
// if bound to a row, must be a table.
|
||||
DataRow row = be.Row;
|
||||
if ( row != null )
|
||||
return row.Table;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
internal static bool IsNotMapped( DataColumn c ) {
|
||||
return c.ColumnMapping == MappingType.Hidden;
|
||||
}
|
||||
|
||||
// ATTENTION: GetRowFromElement( XmlElement ) and GetRowFromElement( XmlBoundElement ) should have the same functionality and side effects.
|
||||
// See this code fragment for why:
|
||||
// XmlBoundElement be = ...;
|
||||
// XmlElement e = be;
|
||||
// GetRowFromElement( be ); // Calls GetRowFromElement( XmlBoundElement )
|
||||
// GetRowFromElement( e ); // Calls GetRowFromElement( XmlElement ), in spite of e beeing an instance of XmlBoundElement
|
||||
internal DataRow GetRowFromElement( XmlElement e ) {
|
||||
XmlBoundElement be = e as XmlBoundElement;
|
||||
if ( be != null )
|
||||
return be.Row;
|
||||
return null;
|
||||
}
|
||||
internal DataRow GetRowFromElement( XmlBoundElement be ) {
|
||||
return be.Row;
|
||||
}
|
||||
|
||||
// Get the row-elem associatd w/ the region node is in.
|
||||
// If node is in a region not mapped (like document element node) the function returns false and sets elem to null)
|
||||
// This function does not work if the region is not associated w/ a DataRow (it uses DataRow association to know what is the row element associated w/ the region)
|
||||
internal bool GetRegion( XmlNode node, out XmlBoundElement rowElem ) {
|
||||
while ( node != null ) {
|
||||
XmlBoundElement be = node as XmlBoundElement;
|
||||
// Break if found a region
|
||||
if ( be != null && GetRowFromElement( be ) != null ) {
|
||||
rowElem = be;
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( node.NodeType == XmlNodeType.Attribute )
|
||||
node = ((XmlAttribute)node).OwnerElement;
|
||||
else
|
||||
node = node.ParentNode;
|
||||
}
|
||||
|
||||
rowElem = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
internal bool IsRegionRadical( XmlBoundElement rowElem ) {
|
||||
// You must pass a row element (which s/b associated w/ a DataRow)
|
||||
Debug.Assert( rowElem.Row != null );
|
||||
|
||||
if ( rowElem.ElementState == ElementState.Defoliated )
|
||||
return true;
|
||||
|
||||
DataTable table = GetTableSchemaForElement( rowElem );
|
||||
DataColumnCollection columns = table.Columns;
|
||||
int iColumn = 0;
|
||||
|
||||
// check column attributes...
|
||||
int cAttrs = rowElem.Attributes.Count;
|
||||
for ( int iAttr = 0; iAttr < cAttrs; iAttr++ ) {
|
||||
XmlAttribute attr = rowElem.Attributes[iAttr];
|
||||
|
||||
// only specified attributes are radical
|
||||
if ( !attr.Specified )
|
||||
return false;
|
||||
|
||||
// only mapped attrs are valid
|
||||
DataColumn schema = GetColumnSchemaForNode( rowElem, attr );
|
||||
if ( schema == null ) {
|
||||
//Console.WriteLine("Region has unmapped attribute");
|
||||
return false;
|
||||
}
|
||||
|
||||
// check to see if column is in order
|
||||
if ( !IsNextColumn( columns, ref iColumn, schema ) ) {
|
||||
//Console.WriteLine("Region has attribute columns out of order or duplicate");
|
||||
return false;
|
||||
}
|
||||
|
||||
// must have exactly one text node (XmlNodeType.Text) child
|
||||
//
|
||||
XmlNode fc = attr.FirstChild;
|
||||
if ( fc == null || fc.NodeType != XmlNodeType.Text || fc.NextSibling != null ) {
|
||||
//Console.WriteLine("column element has other than a single child text node");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// check column elements
|
||||
iColumn = 0;
|
||||
XmlNode n = rowElem.FirstChild;
|
||||
for ( ; n != null; n = n.NextSibling ) {
|
||||
// only elements can exist in radically structured data
|
||||
if ( n.NodeType != XmlNodeType.Element ) {
|
||||
//Console.WriteLine("Region has non-element child");
|
||||
return false;
|
||||
}
|
||||
XmlElement e = n as XmlElement;
|
||||
|
||||
// only checking for column mappings in this loop
|
||||
if ( GetRowFromElement( e ) != null )
|
||||
break;
|
||||
|
||||
// element's must have schema to be radically structured
|
||||
DataColumn schema = GetColumnSchemaForNode( rowElem, e );
|
||||
if ( schema == null ) {
|
||||
//Console.WriteLine("Region has unmapped child element");
|
||||
return false;
|
||||
}
|
||||
|
||||
// check to see if column is in order
|
||||
if ( !IsNextColumn( columns, ref iColumn, schema ) ) {
|
||||
//Console.WriteLine("Region has element columns out of order or duplicate");
|
||||
return false;
|
||||
}
|
||||
|
||||
// must have no attributes
|
||||
if ( e.HasAttributes )
|
||||
return false;
|
||||
|
||||
// must have exactly one text node child
|
||||
XmlNode fc = e.FirstChild;
|
||||
if ( fc == null || fc.NodeType != XmlNodeType.Text || fc.NextSibling != null ) {
|
||||
//Console.WriteLine("column element has other than a single child text node");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// check for remaining sub-regions
|
||||
for (; n != null; n = n.NextSibling ) {
|
||||
// only elements can exist in radically structured data
|
||||
if ( n.NodeType != XmlNodeType.Element ) {
|
||||
//Console.WriteLine("Region has non-element child");
|
||||
return false;
|
||||
}
|
||||
|
||||
// element's must be regions in order to be radially structured
|
||||
DataRow row = GetRowFromElement( (XmlElement)n );
|
||||
if ( row == null ) {
|
||||
//Console.WriteLine("Region has unmapped element");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void AddTableSchema( DataTable table ) {
|
||||
object idTable = GetIdentity( table.EncodedTableName, table.Namespace );
|
||||
tableSchemaMap[ idTable ] = table;
|
||||
}
|
||||
private void AddColumnSchema( DataColumn col ) {
|
||||
DataTable table = col.Table;
|
||||
object idTable = GetIdentity( table.EncodedTableName, table.Namespace );
|
||||
object idColumn = GetIdentity( col.EncodedColumnName, col.Namespace );
|
||||
|
||||
Hashtable columns = (Hashtable) columnSchemaMap[ idTable ];
|
||||
if ( columns == null ) {
|
||||
columns = new Hashtable();
|
||||
columnSchemaMap[ idTable ] = columns;
|
||||
}
|
||||
columns[ idColumn ] = col;
|
||||
}
|
||||
private static object GetIdentity( string localName, string namespaceURI ) {
|
||||
// we need access to XmlName to make this faster
|
||||
return localName+":"+namespaceURI;
|
||||
}
|
||||
|
||||
private bool IsNextColumn( DataColumnCollection columns, ref int iColumn, DataColumn col ) {
|
||||
for ( ; iColumn < columns.Count; iColumn++ ) {
|
||||
if ( columns[iColumn] == col ) {
|
||||
iColumn++; // advance before we return...
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="IXmlDataVirtualNode.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// <owner current="true" primary="true">amirhmy</owner>
|
||||
// <owner current="true" primary="false">markash</owner>
|
||||
// <owner current="false" primary="false">danield</owner>
|
||||
//------------------------------------------------------------------------------
|
||||
namespace System.Xml {
|
||||
|
||||
using System;
|
||||
using System.Data;
|
||||
|
||||
internal interface IXmlDataVirtualNode {
|
||||
bool IsOnNode( XmlNode nodeToCheck );
|
||||
bool IsOnColumn(DataColumn col );
|
||||
bool IsInUse();
|
||||
void OnFoliated( XmlNode foliatedNode );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,181 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="RegionIterator.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// <owner current="true" primary="true">[....]</owner>
|
||||
// <owner current="true" primary="false">[....]</owner>
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma warning disable 618 // ignore obsolete warning about XmlDataDocument
|
||||
namespace System.Xml {
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Text;
|
||||
|
||||
|
||||
internal abstract class BaseRegionIterator : BaseTreeIterator {
|
||||
internal BaseRegionIterator( DataSetMapper mapper ) : base( mapper ) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Iterates over non-attribute nodes
|
||||
internal sealed class RegionIterator : BaseRegionIterator {
|
||||
private XmlBoundElement rowElement;
|
||||
private XmlNode currentNode;
|
||||
|
||||
internal RegionIterator( XmlBoundElement rowElement ) : base( ((XmlDataDocument)(rowElement.OwnerDocument)).Mapper ) {
|
||||
Debug.Assert( rowElement != null && rowElement.Row != null );
|
||||
this.rowElement = rowElement;
|
||||
this.currentNode = rowElement;
|
||||
}
|
||||
|
||||
internal override void Reset() {
|
||||
currentNode = rowElement;
|
||||
}
|
||||
|
||||
internal override XmlNode CurrentNode {
|
||||
get {
|
||||
return currentNode;
|
||||
}
|
||||
}
|
||||
|
||||
internal override bool Next() {
|
||||
XmlNode nextNode;
|
||||
ElementState oldState = rowElement.ElementState;
|
||||
// We do not want to cause any foliation w/ this iterator or use this iterator once the region was defoliated
|
||||
Debug.Assert( oldState != ElementState.None );
|
||||
|
||||
// Try to move to the first child
|
||||
nextNode = currentNode.FirstChild;
|
||||
|
||||
// No children, try next sibling
|
||||
if ( nextNode != null ) {
|
||||
currentNode = nextNode;
|
||||
// If we have been defoliated, we should have stayed that way
|
||||
Debug.Assert( (oldState == ElementState.Defoliated) ? (rowElement.ElementState == ElementState.Defoliated) : true );
|
||||
// Rollback foliation
|
||||
rowElement.ElementState = oldState;
|
||||
return true;
|
||||
}
|
||||
return NextRight();
|
||||
}
|
||||
|
||||
internal override bool NextRight() {
|
||||
// Make sure we do not get past the rowElement if we call NextRight on a just initialized iterator and rowElement has no children
|
||||
if ( currentNode == rowElement ) {
|
||||
currentNode = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
ElementState oldState = rowElement.ElementState;
|
||||
// We do not want to cause any foliation w/ this iterator or use this iterator once the region was defoliated
|
||||
Debug.Assert( oldState != ElementState.None );
|
||||
|
||||
XmlNode nextNode = currentNode.NextSibling;
|
||||
|
||||
if ( nextNode != null ) {
|
||||
currentNode = nextNode;
|
||||
// If we have been defoliated, we should have stayed that way
|
||||
Debug.Assert( (oldState == ElementState.Defoliated) ? (rowElement.ElementState == ElementState.Defoliated) : true );
|
||||
// Rollback foliation
|
||||
rowElement.ElementState = oldState;
|
||||
return true;
|
||||
}
|
||||
|
||||
// No next sibling, try the first sibling of from the parent chain
|
||||
nextNode = currentNode;
|
||||
while ( nextNode != rowElement && nextNode.NextSibling == null )
|
||||
nextNode = nextNode.ParentNode;
|
||||
|
||||
if ( nextNode == rowElement ) {
|
||||
currentNode = null;
|
||||
// If we have been defoliated, we should have stayed that way
|
||||
Debug.Assert( (oldState == ElementState.Defoliated) ? (rowElement.ElementState == ElementState.Defoliated) : true );
|
||||
// Rollback foliation
|
||||
rowElement.ElementState = oldState;
|
||||
return false;
|
||||
}
|
||||
|
||||
currentNode = nextNode.NextSibling;
|
||||
Debug.Assert( currentNode != null );
|
||||
// If we have been defoliated, we should have stayed that way
|
||||
Debug.Assert( (oldState == ElementState.Defoliated) ? (rowElement.ElementState == ElementState.Defoliated) : true );
|
||||
// Rollback foliation
|
||||
rowElement.ElementState = oldState;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Get the initial text value for the current node. You should be positioned on the node (element) for
|
||||
// which to get the initial text value, not on the text node.
|
||||
internal bool NextInitialTextLikeNodes( out String value ) {
|
||||
Debug.Assert( this.CurrentNode != null );
|
||||
Debug.Assert( this.CurrentNode.NodeType == XmlNodeType.Element );
|
||||
#if DEBUG
|
||||
// It's not OK to try to read the initial text value for sub-regions, because we do not know how to revert their initial state
|
||||
if ( this.CurrentNode.NodeType == XmlNodeType.Element && mapper.GetTableSchemaForElement( (XmlElement)(this.CurrentNode) ) != null ) {
|
||||
if ( this.CurrentNode != rowElement )
|
||||
Debug.Assert( false );
|
||||
}
|
||||
#endif
|
||||
|
||||
ElementState oldState = rowElement.ElementState;
|
||||
// We do not want to cause any foliation w/ this iterator or use this iterator once the region was defoliated
|
||||
Debug.Assert( oldState != ElementState.None );
|
||||
|
||||
XmlNode n = this.CurrentNode.FirstChild;
|
||||
value = GetInitialTextFromNodes( ref n );
|
||||
if ( n == null ) {
|
||||
// If we have been defoliated, we should have stayed that way
|
||||
Debug.Assert( (oldState == ElementState.Defoliated) ? (rowElement.ElementState == ElementState.Defoliated) : true );
|
||||
// Rollback eventual foliation
|
||||
rowElement.ElementState = oldState;
|
||||
return NextRight();
|
||||
}
|
||||
Debug.Assert( ! XmlDataDocument.IsTextLikeNode( n ) );
|
||||
currentNode = n;
|
||||
// If we have been defoliated, we should have stayed that way
|
||||
Debug.Assert( (oldState == ElementState.Defoliated) ? (rowElement.ElementState == ElementState.Defoliated) : true );
|
||||
// Rollback eventual foliation
|
||||
rowElement.ElementState = oldState;
|
||||
return true;
|
||||
}
|
||||
|
||||
private static string GetInitialTextFromNodes( ref XmlNode n ) {
|
||||
string value = null;
|
||||
|
||||
if ( n != null ) {
|
||||
// don't consider whitespace
|
||||
while ( n.NodeType == XmlNodeType.Whitespace ) {
|
||||
n = n.NextSibling;
|
||||
if ( n == null )
|
||||
return String.Empty;
|
||||
}
|
||||
|
||||
if ( XmlDataDocument.IsTextLikeNode( n ) && (n.NextSibling == null || ! XmlDataDocument.IsTextLikeNode( n.NextSibling )) ) {
|
||||
// don't use string builder if only one text node exists
|
||||
value = n.Value;
|
||||
n = n.NextSibling;
|
||||
}
|
||||
else {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
while ( n != null && XmlDataDocument.IsTextLikeNode( n ) ) {
|
||||
// Ignore non-significant whitespace nodes
|
||||
if ( n.NodeType != XmlNodeType.Whitespace )
|
||||
sb.Append( n.Value );
|
||||
n = n.NextSibling;
|
||||
}
|
||||
value = sb.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
if ( value == null )
|
||||
value = String.Empty;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="TreeIterator.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// <owner current="true" primary="true">[....]</owner>
|
||||
// <owner current="true" primary="false">[....]</owner>
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma warning disable 618 // ignore obsolete warning about XmlDataDocument
|
||||
namespace System.Xml {
|
||||
using System.Diagnostics;
|
||||
|
||||
// Iterates over non-attribute nodes
|
||||
internal sealed class TreeIterator : BaseTreeIterator {
|
||||
private XmlNode nodeTop;
|
||||
private XmlNode currentNode;
|
||||
|
||||
internal TreeIterator( XmlNode nodeTop ) : base( ((XmlDataDocument)(nodeTop.OwnerDocument)).Mapper ) {
|
||||
Debug.Assert( nodeTop != null );
|
||||
this.nodeTop = nodeTop;
|
||||
this.currentNode = nodeTop;
|
||||
}
|
||||
|
||||
internal override void Reset() {
|
||||
currentNode = nodeTop;
|
||||
}
|
||||
|
||||
internal override XmlNode CurrentNode {
|
||||
get {
|
||||
return currentNode;
|
||||
}
|
||||
}
|
||||
|
||||
internal override bool Next() {
|
||||
XmlNode nextNode;
|
||||
|
||||
// Try to move to the first child
|
||||
nextNode = currentNode.FirstChild;
|
||||
|
||||
// No children, try next sibling
|
||||
if ( nextNode != null ) {
|
||||
currentNode = nextNode;
|
||||
return true;
|
||||
}
|
||||
return NextRight();
|
||||
}
|
||||
|
||||
internal override bool NextRight() {
|
||||
// Make sure we do not get past the nodeTop if we call NextRight on a just initialized iterator and nodeTop has no children
|
||||
if ( currentNode == nodeTop ) {
|
||||
currentNode = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
XmlNode nextNode = currentNode.NextSibling;
|
||||
|
||||
if ( nextNode != null ) {
|
||||
currentNode = nextNode;
|
||||
return true;
|
||||
}
|
||||
|
||||
// No next sibling, try the first sibling of from the parent chain
|
||||
nextNode = currentNode;
|
||||
while ( nextNode != nodeTop && nextNode.NextSibling == null )
|
||||
nextNode = nextNode.ParentNode;
|
||||
|
||||
if ( nextNode == nodeTop ) {
|
||||
currentNode = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
currentNode = nextNode.NextSibling;
|
||||
Debug.Assert( currentNode != null );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,331 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="XmlBoundElement.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// <owner current="true" primary="true">[....]</owner>
|
||||
// <owner current="false" primary="false">[....]</owner>
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma warning disable 618 // ignore obsolete warning about XmlDataDocument
|
||||
namespace System.Xml {
|
||||
using System.Data;
|
||||
using System.Diagnostics;
|
||||
|
||||
internal enum ElementState {
|
||||
None,
|
||||
Defoliated,
|
||||
WeakFoliation,
|
||||
StrongFoliation,
|
||||
Foliating,
|
||||
Defoliating,
|
||||
}
|
||||
|
||||
internal sealed class XmlBoundElement: XmlElement {
|
||||
private DataRow row;
|
||||
private ElementState state;
|
||||
|
||||
internal XmlBoundElement( string prefix, string localName, string namespaceURI, XmlDocument doc )
|
||||
: base( prefix, localName, namespaceURI, doc ) {
|
||||
state = ElementState.None;
|
||||
}
|
||||
|
||||
public override XmlAttributeCollection Attributes {
|
||||
get {
|
||||
AutoFoliate();
|
||||
return base.Attributes;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool HasAttributes {
|
||||
get { return Attributes.Count > 0; }
|
||||
}
|
||||
|
||||
public override XmlNode FirstChild {
|
||||
get {
|
||||
AutoFoliate();
|
||||
return base.FirstChild;
|
||||
}
|
||||
}
|
||||
|
||||
internal XmlNode SafeFirstChild { get { return base.FirstChild; } }
|
||||
|
||||
public override XmlNode LastChild {
|
||||
get {
|
||||
AutoFoliate();
|
||||
return base.LastChild;
|
||||
}
|
||||
}
|
||||
|
||||
public override XmlNode PreviousSibling {
|
||||
get {
|
||||
XmlNode prev = base.PreviousSibling;
|
||||
if ( prev == null ) {
|
||||
XmlBoundElement parent = ParentNode as XmlBoundElement;
|
||||
if ( parent != null ) {
|
||||
parent.AutoFoliate();
|
||||
return base.PreviousSibling;
|
||||
}
|
||||
}
|
||||
return prev;
|
||||
}
|
||||
}
|
||||
|
||||
internal XmlNode SafePreviousSibling { get { return base.PreviousSibling; } }
|
||||
|
||||
public override XmlNode NextSibling {
|
||||
get {
|
||||
XmlNode next = base.NextSibling;
|
||||
if ( next == null ) {
|
||||
XmlBoundElement parent = ParentNode as XmlBoundElement;
|
||||
if ( parent != null ) {
|
||||
parent.AutoFoliate();
|
||||
return base.NextSibling;
|
||||
}
|
||||
}
|
||||
return next;
|
||||
}
|
||||
}
|
||||
|
||||
internal XmlNode SafeNextSibling { get { return base.NextSibling; } }
|
||||
|
||||
public override bool HasChildNodes {
|
||||
get {
|
||||
AutoFoliate();
|
||||
return base.HasChildNodes;
|
||||
}
|
||||
}
|
||||
|
||||
public override XmlNode InsertBefore(XmlNode newChild, XmlNode refChild) {
|
||||
AutoFoliate();
|
||||
return base.InsertBefore( newChild, refChild );
|
||||
}
|
||||
|
||||
public override XmlNode InsertAfter(XmlNode newChild, XmlNode refChild) {
|
||||
AutoFoliate();
|
||||
return base.InsertAfter( newChild, refChild );
|
||||
}
|
||||
|
||||
public override XmlNode ReplaceChild(XmlNode newChild, XmlNode oldChild) {
|
||||
AutoFoliate();
|
||||
return base.ReplaceChild( newChild, oldChild );
|
||||
}
|
||||
|
||||
public override XmlNode AppendChild(XmlNode newChild) {
|
||||
AutoFoliate();
|
||||
return base.AppendChild( newChild );
|
||||
}
|
||||
|
||||
internal void RemoveAllChildren() {
|
||||
XmlNode child = FirstChild;
|
||||
XmlNode sibling = null;
|
||||
|
||||
while ( child != null ) {
|
||||
sibling = child.NextSibling;
|
||||
RemoveChild( child );
|
||||
child = sibling;
|
||||
}
|
||||
}
|
||||
|
||||
public override string InnerXml {
|
||||
get {
|
||||
return base.InnerXml;
|
||||
}
|
||||
set {
|
||||
|
||||
RemoveAllChildren();
|
||||
|
||||
XmlDataDocument doc = (XmlDataDocument) OwnerDocument;
|
||||
|
||||
bool bOrigIgnoreXmlEvents = doc.IgnoreXmlEvents;
|
||||
bool bOrigIgnoreDataSetEvents = doc.IgnoreDataSetEvents;
|
||||
|
||||
doc.IgnoreXmlEvents = true;
|
||||
doc.IgnoreDataSetEvents = true;
|
||||
|
||||
base.InnerXml = value;
|
||||
|
||||
doc.SyncTree( this );
|
||||
|
||||
doc.IgnoreDataSetEvents = bOrigIgnoreDataSetEvents;
|
||||
doc.IgnoreXmlEvents = bOrigIgnoreXmlEvents;
|
||||
}
|
||||
}
|
||||
|
||||
internal DataRow Row {
|
||||
get { return row;}
|
||||
set { row = value;}
|
||||
}
|
||||
|
||||
internal bool IsFoliated {
|
||||
get {
|
||||
while ( state == ElementState.Foliating || state == ElementState.Defoliating )
|
||||
System.Threading.Thread.Sleep(0);
|
||||
//has to be sure that we are either foliated or defoliated when ask for IsFoliated.
|
||||
return state != ElementState.Defoliated;
|
||||
}
|
||||
}
|
||||
|
||||
internal ElementState ElementState {
|
||||
get { return state;}
|
||||
set { state = value;}
|
||||
}
|
||||
|
||||
internal void Foliate( ElementState newState ) {
|
||||
XmlDataDocument doc = (XmlDataDocument) OwnerDocument;
|
||||
if ( doc != null )
|
||||
doc.Foliate( this, newState );
|
||||
}
|
||||
|
||||
// Foliate the node as a side effect of user calling functions on this node (like NextSibling) OR as a side effect of DataDocNav using nodes to do editing
|
||||
private void AutoFoliate() {
|
||||
XmlDataDocument doc = (XmlDataDocument) OwnerDocument;
|
||||
if ( doc != null )
|
||||
doc.Foliate( this, doc.AutoFoliationState );
|
||||
}
|
||||
|
||||
public override XmlNode CloneNode(bool deep) {
|
||||
XmlDataDocument doc = (XmlDataDocument)(this.OwnerDocument);
|
||||
ElementState oldAutoFoliationState = doc.AutoFoliationState;
|
||||
doc.AutoFoliationState = ElementState.WeakFoliation;
|
||||
XmlElement element;
|
||||
try {
|
||||
Foliate( ElementState.WeakFoliation );
|
||||
element = (XmlElement)(base.CloneNode( deep ));
|
||||
// Clone should create a XmlBoundElement node
|
||||
Debug.Assert( element is XmlBoundElement );
|
||||
}
|
||||
finally {
|
||||
doc.AutoFoliationState = oldAutoFoliationState;
|
||||
}
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
public override void WriteContentTo( XmlWriter w ) {
|
||||
DataPointer dp = new DataPointer( (XmlDataDocument)OwnerDocument, this );
|
||||
try {
|
||||
dp.AddPointer();
|
||||
WriteBoundElementContentTo( dp, w );
|
||||
}
|
||||
finally {
|
||||
dp.SetNoLongerUse();
|
||||
}
|
||||
}
|
||||
|
||||
public override void WriteTo( XmlWriter w ) {
|
||||
DataPointer dp = new DataPointer( (XmlDataDocument)OwnerDocument, this );
|
||||
try {
|
||||
dp.AddPointer();
|
||||
WriteRootBoundElementTo( dp, w );
|
||||
}
|
||||
finally {
|
||||
dp.SetNoLongerUse();
|
||||
}
|
||||
}
|
||||
|
||||
private void WriteRootBoundElementTo(DataPointer dp, XmlWriter w) {
|
||||
Debug.Assert( dp.NodeType == XmlNodeType.Element );
|
||||
XmlDataDocument doc = (XmlDataDocument)OwnerDocument;
|
||||
w.WriteStartElement( dp.Prefix, dp.LocalName, dp.NamespaceURI );
|
||||
int cAttr = dp.AttributeCount;
|
||||
bool bHasXSI = false;
|
||||
if ( cAttr > 0 ) {
|
||||
for ( int iAttr = 0; iAttr < cAttr; iAttr++ ) {
|
||||
dp.MoveToAttribute( iAttr );
|
||||
if ( dp.Prefix == "xmlns" && dp.LocalName == XmlDataDocument.XSI )
|
||||
bHasXSI = true;
|
||||
WriteTo( dp, w );
|
||||
dp.MoveToOwnerElement();
|
||||
}
|
||||
}
|
||||
|
||||
if ( !bHasXSI && doc.bLoadFromDataSet && doc.bHasXSINIL )
|
||||
w.WriteAttributeString( "xmlns", "xsi", "http://www.w3.org/2000/xmlns/", Keywords.XSINS );
|
||||
|
||||
|
||||
WriteBoundElementContentTo( dp, w );
|
||||
|
||||
// Force long end tag when the elem is not empty, even if there are no children.
|
||||
if ( dp.IsEmptyElement )
|
||||
w.WriteEndElement();
|
||||
else
|
||||
w.WriteFullEndElement();
|
||||
}
|
||||
|
||||
private static void WriteBoundElementTo( DataPointer dp, XmlWriter w ) {
|
||||
Debug.Assert( dp.NodeType == XmlNodeType.Element );
|
||||
w.WriteStartElement( dp.Prefix, dp.LocalName, dp.NamespaceURI );
|
||||
int cAttr = dp.AttributeCount;
|
||||
if ( cAttr > 0 ) {
|
||||
for ( int iAttr = 0; iAttr < cAttr; iAttr++ ) {
|
||||
dp.MoveToAttribute( iAttr );
|
||||
WriteTo( dp, w );
|
||||
dp.MoveToOwnerElement();
|
||||
}
|
||||
}
|
||||
|
||||
WriteBoundElementContentTo( dp, w );
|
||||
|
||||
// Force long end tag when the elem is not empty, even if there are no children.
|
||||
if ( dp.IsEmptyElement )
|
||||
w.WriteEndElement();
|
||||
else
|
||||
w.WriteFullEndElement();
|
||||
}
|
||||
|
||||
private static void WriteBoundElementContentTo( DataPointer dp, XmlWriter w ) {
|
||||
if ( !dp.IsEmptyElement && dp.MoveToFirstChild() ) {
|
||||
do {
|
||||
WriteTo( dp, w );
|
||||
}
|
||||
while ( dp.MoveToNextSibling() );
|
||||
|
||||
dp.MoveToParent();
|
||||
}
|
||||
}
|
||||
|
||||
private static void WriteTo( DataPointer dp, XmlWriter w ) {
|
||||
switch ( dp.NodeType ) {
|
||||
case XmlNodeType.Attribute:
|
||||
if ( !dp.IsDefault ) {
|
||||
w.WriteStartAttribute( dp.Prefix, dp.LocalName, dp.NamespaceURI );
|
||||
|
||||
if ( dp.MoveToFirstChild() ) {
|
||||
do {
|
||||
WriteTo( dp, w );
|
||||
}
|
||||
while ( dp.MoveToNextSibling() );
|
||||
|
||||
dp.MoveToParent();
|
||||
}
|
||||
|
||||
w.WriteEndAttribute();
|
||||
}
|
||||
break;
|
||||
|
||||
case XmlNodeType.Element:
|
||||
WriteBoundElementTo( dp, w );
|
||||
break;
|
||||
|
||||
case XmlNodeType.Text:
|
||||
w.WriteString(dp.Value);
|
||||
break;
|
||||
|
||||
default:
|
||||
Debug.Assert( ((IXmlDataVirtualNode)dp).IsOnColumn( null ) );
|
||||
if ( dp.GetNode() != null )
|
||||
dp.GetNode().WriteTo( w );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override XmlNodeList GetElementsByTagName(string name) {
|
||||
// Retrieving nodes from the returned nodelist may cause foliation which causes new nodes to be created,
|
||||
// so the System.Xml iterator will throw if this happens during iteration. To avoid this, foliate everything
|
||||
// before iteration, so iteration will not cause foliation (and as a result of this, creation of new nodes).
|
||||
XmlNodeList tempNodeList = base.GetElementsByTagName(name);
|
||||
|
||||
int tempint = tempNodeList.Count;
|
||||
return tempNodeList;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
c2b65001e20fdf4314b416854c964de726333424
|
||||
@@ -0,0 +1,21 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <copyright file="XmlDataImplementation.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// <owner current="true" primary="true">[....]</owner>
|
||||
// <owner current="true" primary="false">[....]</owner>
|
||||
//------------------------------------------------------------------------------
|
||||
#pragma warning disable 618 // ignore obsolete warning about XmlDataDocument
|
||||
namespace System.Xml {
|
||||
|
||||
internal sealed class XmlDataImplementation : XmlImplementation {
|
||||
|
||||
public XmlDataImplementation() : base() {
|
||||
}
|
||||
|
||||
public override XmlDocument CreateDocument() {
|
||||
return new XmlDataDocument( this );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user