"Bill Cohagan" <bi**@teraXNOSPAMXquest.com> wrote in message news:uT**************@TK2MSFTNGP11.phx.gbl...
In my app I'm validating an XML file against an XSD which contains several
attribute default value specifications.
: : when I serialize the resulting doc using its WriteContentTo method,
the default attributes are NOT represented in the XML output stream. Is this
expected behaviour and, if so, how can I arrange to retain these default
attribute values?
WriteContentTo( ) could have any of three motivations:
1.) It could generate an XML serialization preserving as much of the
original XML serialization as possible, including insignificant white
space and the quote characters delimiting each attribute value.
(I'd dismiss this as it imposes too heavy of a burden to maintain
knowledge of the original serialization format. The XML Infoset
is unconcerned with these minutia which it sees as irrelevant
artifacts of the serialization. XmlDocument is a model of the
Infoset.)
2.) It could generate XML that is canonically equivalent to the
original serialization format. This disregards irrelevant minutia,
such as the quantity of whitespace between attributes in an
element tag. It preserves those details of importance when
two XML documents must be compared for equivalence; which
has important applications in XML Encryption and XML Digital
Signatures.
3.) It could produce the Post Schema Validation Infoset (or PSVI),
if available. The PSVI contains value-added information from the
schema validation process, such as default attribute values, that
were not present in the original document. While additive, this
creates a document which is not equivalent to the original source,
and under some circumstances might be undesirable.
As one example of where producing the PSVI could be a mistake,
suppose I have an XML document with a child element, Account.
Account may have an attribute, MaxFDICInsuredBalance, defined
in the XML Schema as having the default value of $100,000.00.
Being a bank, I'll want to digitally sign the Account element to both
preserve its integrity (detect any alteration) and authenticate myself
(or my back-end process) as being the last person to modify it.
What happens if I schema-validate this digitally-signed document
in a ValidatingXmlReader and then pass it along to another process
that verifies the authenticity of the digital signature? 'Lo and behold,
should WriteContentTo( ) produce a serialization based on the PSVI
rather than one thats canonically equivalent to the original signed
document, the Account element has been tampered with!
Looking at it more closely, the explicit content of the Account element
would've changed were a WriteContentTo( ) to serialize the PSVI.
It would now contain the implied attribute value of $100,000.00 for
MaxFDICInsuredBalance, whereas the Account element was signed
when that wasn't present.
If WriteContentTo( ) did intend to serialize the document in a canonically
equivalent representation of its original content (rather than the serialize
the document's PSVI including default attribute nodes), I imagine it would
employ the IsDefault property of XmlReader to do so.
This nugget may suggest an answer to your second question, how to retain
the default attribute values?
Try subclassing ValidatingXmlReader and override the virtual IsDefault
property to always return false.
- - - KeepPsviDefAttrs.cs
using System.Xml;
public class MyValidatingXmlReader : ValidatingXmlReader {
public override bool IsDefault { get { return false; } }
}
- - -
Then use this MyValidatingXmlReader when loading the XmlDocument.
Whenever WriteContentTo( ) asks whether a given attribute node should
be serialized because it was added as a default value, you can direct
WriteContentTo( ) to ignore this distinction (serialize all attributes whether
they are default or not).
HTH,
Derek Harmon