private void ProcessAttributes(ParseRecord pr, ParseRecord objectPr)
{
InternalST.Soap( this, "ProcessAttributes Entry ",pr.Trace()," headerState ",((Enum)headerState).ToString());
String keyPosition = null;
String keyOffset = null;
String keyMustUnderstand = null;
pr.PRisProcessAttributes = true;
String SoapKeyUrl = "http://schemas.xmlsoap.org/soap/encoding/";
int SoapKeyUrlLength = SoapKeyUrl.Length;
String UrtKeyUrl = "http://schemas.microsoft.com/clr/id";
int UrtKeyUrlLength = UrtKeyUrl.Length;
String SoapEnvKeyUrl = "http://schemas.xmlsoap.org/soap/envelope/";
int SoapEnvKeyUrlLength = SoapEnvKeyUrl.Length;
String XSIKey2001 = "http://www.w3.org/2001/XMLSchema-instance";
int XSIKey2001Length = XSIKey2001.Length;
String XSIKey2000 = "http://www.w3.org/2000/10/XMLSchema-instance";
int XSIKey2000Length = XSIKey2000.Length;
String XSIKey1999 = "http://www.w3.org/1999/XMLSchema-instance";
int XSIKey1999Length = XSIKey1999.Length;
String XSDKey1999 = "http://www.w3.org/1999/XMLSchema";
int XSDKey1999Length = XSDKey1999.Length;
String XSDKey2000 = "http://www.w3.org/2000/10/XMLSchema";
int XSDKey2000Length = XSDKey2000.Length;
String XSDKey2001 = "http://www.w3.org/2001/XMLSchema";
int XSDKey2001Length = XSDKey2001.Length;
String clrNS = "http://schemas.microsoft.com/soap/encoding/clr/1.0";
int clrNSLength = clrNS.Length;
for (int i = 0; i<attributeValues.Count(); i++)
{
AttributeValueEntry attributeValueEntry = (AttributeValueEntry)attributeValues.GetItem(i);
String prefix = attributeValueEntry.prefix;
String key = attributeValueEntry.key;
if ((key == null) || (key.Length == 0))
key = pr.PRnameXmlKey; //case where there is a default key
String value = attributeValueEntry.value;
bool prefixMatchesXmlns = false;
String urn = attributeValueEntry.urn;
InternalST.Soap( this, "ProcessAttributes attribute prefix ",prefix," key ",key," value ",value," urn ", urn);
int keyLength = key.Length;
int valueLength = value.Length;
// table need for QName xsd types
if (key == null || keyLength == 0)
keyToNamespaceTable[prefix] = value;
else
keyToNamespaceTable[prefix+":"+key] = value;
if (keyLength == 2 && String.Compare(key, "id", true, CultureInfo.InvariantCulture) == 0)
pr.PRobjectId = objectReader.GetId(value);
else if (keyLength == 8 && String.Compare(key, "position", true, CultureInfo.InvariantCulture) == 0)
keyPosition = value;
else if (keyLength == 6 && String.Compare(key, "offset", true, CultureInfo.InvariantCulture) == 0)
keyOffset = value;
else if (keyLength == 14 && String.Compare(key, "MustUnderstand", true, CultureInfo.InvariantCulture) == 0)
keyMustUnderstand = value;
else if (keyLength == 4 && String.Compare(key, "null", true, CultureInfo.InvariantCulture) == 0)
{
pr.PRmemberValueEnum = InternalMemberValueE.Null;
pr.PRvalue = null;
}
else if (keyLength == 4 && String.Compare(key, "root", true, CultureInfo.InvariantCulture) == 0)
{
if (value.Equals("1"))
pr.PRisHeaderRoot = true;
}
else if (keyLength == 4 && String.Compare(key, "href", true, CultureInfo.InvariantCulture) == 0)
pr.PRidRef = objectReader.GetId(value);
else if (keyLength == 4 && String.Compare(key, "type", true, CultureInfo.InvariantCulture) == 0)
{
String currentPRtypeXmlKey = pr.PRtypeXmlKey;
String currentPRkeyDt = pr.PRkeyDt;
Type currentPRdtType = pr.PRdtType;
String typeValue = value;
int index = value.IndexOf(":");
if (index > 0)
{
pr.PRtypeXmlKey = value.Substring(0, index);
typeValue = value.Substring(++index);
}
else
{
pr.PRtypeXmlKey = prefix;
}
if (String.Compare(typeValue, "anyType", true, CultureInfo.InvariantCulture) == 0 || String.Compare(typeValue, "ur-type", true, CultureInfo.InvariantCulture) == 0)
{
pr.PRkeyDt = "System.Object";
pr.PRdtType = SoapUtil.typeofObject;
pr.PRtypeXmlKey = urtKey;
}
if (pr.PRtypeXmlKey == soapKey && typeValue == "Array") //Don't need to process xsi:type="SOAP-ENC:Array"
{
// Array values already found,use these value rather then the xsi:type values
pr.PRtypeXmlKey = currentPRtypeXmlKey;
pr.PRkeyDt = currentPRkeyDt;
pr.PRdtType = currentPRdtType;
InternalST.Soap( this,"ProcessAttributes, xsi:type='SOAP-ENC:Array' pr.PRtypeXmlKey ", pr.PRtypeXmlKey," pr.PRkeyDt "+pr.PRkeyDt);
}
else
{
pr.PRkeyDt = typeValue;
InternalST.Soap( this,"ProcessAttributes, not xsi:type='SOAP-ENC:Array' pr.PRtypeXmlKey ", pr.PRtypeXmlKey," pr.PRkeyDt "+pr.PRkeyDt);
}
}
else if (keyLength == 9 && String.Compare(key, "arraytype", true, CultureInfo.InvariantCulture) == 0)
{
String typeValue = value;
int index = value.IndexOf(":");
if (index > 0)
{
pr.PRtypeXmlKey = value.Substring(0, index);
pr.PRkeyDt = typeValue = value.Substring(++index);
}
if (typeValue.StartsWith("ur_type["))
{
pr.PRkeyDt = "System.Object"+typeValue.Substring(6);
pr.PRtypeXmlKey = urtKey;
}
}
else if (SoapServices.IsClrTypeNamespace(value))
{
if (!assemKeyToAssemblyTable.ContainsKey(key))
{
String typeNamespace = null;
String assemblyName = null;
SoapServices.DecodeXmlNamespaceForClrTypeNamespace(value, out typeNamespace, out assemblyName);
if (assemblyName == null)
{
assemKeyToAssemblyTable[key] = new SoapAssemblyInfo(SoapUtil.urtAssemblyString, SoapUtil.urtAssembly);
assemKeyToNameSpaceTable[key] = typeNamespace;
}
else
{
assemKeyToAssemblyTable[key] = new SoapAssemblyInfo(assemblyName);
if (typeNamespace != null)
assemKeyToNameSpaceTable[key] = typeNamespace;
}
}
}
else if ((prefixMatchesXmlns = prefix.Equals("xmlns")) && (valueLength == SoapKeyUrlLength && String.Compare(value, SoapKeyUrl, true, CultureInfo.InvariantCulture) == 0))
{
soapKey = key;
}
else if (prefixMatchesXmlns && (valueLength == UrtKeyUrlLength && String.Compare(value, UrtKeyUrl, true, CultureInfo.InvariantCulture) == 0))
{
urtKey = key;
assemKeyToAssemblyTable[urtKey] = new SoapAssemblyInfo(SoapUtil.urtAssemblyString, SoapUtil.urtAssembly);
}
else if (prefixMatchesXmlns && (valueLength == SoapEnvKeyUrlLength && String.Compare(value, SoapEnvKeyUrl, true) == 0))
{
soapEnvKey = key;
}
else if (key == "encodingStyle")
{
/*
String[] split = value.Split(' ');
foreach (String s in split)
{
if (s == "http://schemas.microsoft.com/soap/encoding/clr/1.0")
{
objectReader.SetVersion(1,0);
break;
}
}
*/
}
else if (prefixMatchesXmlns &&
((valueLength == XSIKey2001Length && String.Compare(value, XSIKey2001,true, CultureInfo.InvariantCulture) == 0) ||
(valueLength == XSIKey1999Length && String.Compare(value, XSIKey1999,true, CultureInfo.InvariantCulture) == 0) ||
(valueLength == XSIKey2000Length && String.Compare(value, XSIKey2000,true, CultureInfo.InvariantCulture) == 0)))
{
xsiKey = key;
}
else if (prefixMatchesXmlns &&
((valueLength == XSDKey2001Length && String.Compare(value, XSDKey2001 , true, CultureInfo.InvariantCulture) == 0)) ||
(valueLength == XSDKey1999Length && String.Compare(value, XSDKey1999, true, CultureInfo.InvariantCulture) == 0) ||
(valueLength == XSDKey2000Length && String.Compare(value, XSDKey2000, true, CultureInfo.InvariantCulture) == 0))
{
xsdKey = key;
}
else if (prefixMatchesXmlns && (valueLength == clrNSLength && String.Compare(value, clrNS, true, CultureInfo.InvariantCulture) == 0))
{
objectReader.SetVersion(1,0);
}
else
{
//String lowerCaseValue = value.ToLower(CultureInfo.InvariantCulture);
if (prefixMatchesXmlns)
{
// Assume it is an interop namespace
assemKeyToInteropAssemblyTable[key] = value;
InternalST.Soap( this,"ProcessAttributes, InteropType key "+key+" value ",value);
}
else if (String.Compare(prefix, soapKey, true, CultureInfo.InvariantCulture) == 0)
{
InternalST.Soap( this,"ProcessAttributes, Not processed key ",prefix,":",key," = ",value);
}
else
{
// See if it is a XmlAttribute
InternalST.Soap( this,"ProcessAttributes, XmlAttribute prefix ",prefix," key ",key," value ",value," urn ",urn, " hashtable ",assemKeyToInteropAssemblyTable[prefix]);
if ((assemKeyToInteropAssemblyTable.ContainsKey(prefix)) && ((String)assemKeyToInteropAssemblyTable[prefix]).Equals(urn))
{
ProcessXmlAttribute(prefix, key, value, objectPr);
}
else
{
InternalST.Soap( this,"ProcessAttributes, Not processed prefix ",prefix," key ",key," value ",value," urn ",urn);
}
}
}
}
attributeValues.Clear();
// reset the header state
// If no headers then headerState is None
//
// if parent is a header section then these are top level objects
// within the header section. If the object has a root set
// then it is a header record, if not then it is a toplevel object
// in the header section which is not a header record.
//
// if the parent is not a header section and is a header root
// then this is a nested object within a header record. All
// subsequent object will be nested until another header
// root is encountered
//
// The first header record is considered a root record
if (headerState != HeaderStateEnum.None)
{
if (objectPr.PRparseTypeEnum == InternalParseTypeE.Headers)
{
if (pr.PRisHeaderRoot || (headerState == HeaderStateEnum.FirstHeaderRecord))
{
headerState = HeaderStateEnum.HeaderRecord;
}
else
{
headerState = HeaderStateEnum.TopLevelObject;
currentState = InternalParseStateE.Object;
pr.PRobjectTypeEnum = InternalObjectTypeE.Object;
pr.PRparseTypeEnum = InternalParseTypeE.Object;
pr.PRparseStateEnum = InternalParseStateE.Object;
pr.PRmemberTypeEnum = InternalMemberTypeE.Empty;
pr.PRmemberValueEnum = InternalMemberValueE.Empty;
}
}
else if (objectPr.PRisHeaderRoot)
headerState = HeaderStateEnum.NestedObject;
}
InternalST.Soap( this,"ProcessAttributes, headerState ",((Enum)headerState).ToString());
if (!isTopFound && (objectPr != null ) && (objectPr.PRparseTypeEnum == InternalParseTypeE.Body))
{
pr.PRobjectPositionEnum = InternalObjectPositionE.Top;
isTopFound = true;
}
else if (pr.PRobjectPositionEnum != InternalObjectPositionE.Top)
pr.PRobjectPositionEnum = InternalObjectPositionE.Child;
// Don't process type for envelop, topSoapElement unless it has a key of soapEnvKey (SOAP-ENV). Fault
// is the only top record which currently falls into this category.
if (!((pr.PRparseTypeEnum == InternalParseTypeE.Envelope)||
(pr.PRparseTypeEnum == InternalParseTypeE.Body) ||
(pr.PRparseTypeEnum == InternalParseTypeE.Headers) ||
(pr.PRobjectPositionEnum == InternalObjectPositionE.Top &&
objectReader.IsFakeTopObject &&
!pr.PRnameXmlKey.Equals(soapEnvKey))))
{
InternalST.Soap( this, "ProcessAttributes before Process Type ",((Enum)pr.PRparseTypeEnum).ToString());
ProcessType(pr, objectPr);
}
if (keyPosition != null)
{
int outRank;
String outDimSignature;
InternalArrayTypeE outArrayTypeEnum;
pr.PRpositionA = ParseArrayDimensions(keyPosition, out outRank, out outDimSignature, out outArrayTypeEnum);
}
if (keyOffset != null)
{
int outRank;
String outDimSignature;
InternalArrayTypeE outArrayTypeEnum;
pr.PRlowerBoundA = ParseArrayDimensions(keyOffset, out outRank, out outDimSignature, out outArrayTypeEnum);
}
if (keyMustUnderstand != null)
if (keyMustUnderstand.Equals("1"))
pr.PRisMustUnderstand = true;
else if (keyMustUnderstand.Equals("0"))
pr.PRisMustUnderstand = false;
else
throw new SerializationException(String.Format(SoapUtil.GetResourceString("Serialization_MustUnderstand"),keyMustUnderstand));
if (pr.PRparseTypeEnum == InternalParseTypeE.Member)
{
// Process Member
InternalST.Soap( this, "ProcessAttributes Member ");
stack.Dump();
if (objectPr.PRparseTypeEnum == InternalParseTypeE.Headers)
pr.PRmemberTypeEnum = InternalMemberTypeE.Header;
else if (objectPr.PRobjectTypeEnum == InternalObjectTypeE.Array)
pr.PRmemberTypeEnum = InternalMemberTypeE.Item;
else
pr.PRmemberTypeEnum = InternalMemberTypeE.Field;
}
}