471,077 Members | 961 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 471,077 software developers and data experts.

Insert Doctype Node Dynamically

I am receiving xml documents from a customer without a reference to a
doctype. I know what the Doctype DTD should be need to insert the
declaration as follows

<?xml version="1.0" encoding="UTF-8"?>
<!-- start of add validation tag -->
<!DOCTYPE D1XML SYSTEM "http://url/myDTD.DTD">
<!-- end of add validation tag -->
<XML.....>

Using one of the provided framework classes such as XmlValidatingReader,
etc.... is there a method to dynamically add a doctype reference? Or do I
have to find the starting node and perform an insert to the doctype
afterwards? Bottom line is I need a foolproof way to add this doctype
reference in the right spot each time.

For all of you asking, "Why...." The customer will be adding this DTD
reference shortly, but for now this is the "band-aid" that needs to be
applied.

Thanks for your help.
Nov 12 '05 #1
1 3987
"Chris Fink" <ch********@gmail.com> wrote in message news:%2****************@TK2MSFTNGP10.phx.gbl...
I am receiving xml documents from a customer without a reference to a
doctype. I know what the Doctype DTD should be need to insert the
declaration as follows

<?xml version="1.0" encoding="UTF-8"?>
<!-- start of add validation tag -->
<!DOCTYPE D1XML SYSTEM "http://url/myDTD.DTD">
<!-- end of add validation tag -->
<XML.....>

Using one of the provided framework classes such as XmlValidatingReader,
etc.... is there a method to dynamically add a doctype reference?


While streaming it through an XmlValidatingReader, one possibility
is to subclass one of the Reader classes from the System.IO name-
space to insert the additional line(s) you seek for the reference to
an external DTD.

Here is an example of such a class that could do this (I only impl'd
the Read(char[],int,int) method because in a quick test, that's what
was used when loading an XmlDocument as you may if you wrap
this Reader in an XmlTextReader -- so your mileage may vary.)

- - - InsertLineStreamReader.cs (partial)
using System;
using System.Collections;
using System.IO;

namespace Derek.IO
{
public class InsertLineStreamReader : System.IO.StreamReader
{
private delegate int ReadMethod(char[] buffer, int index, int count);

string insertStr;
int lineNo, readNo, overflowIndex;
char[] overflow;

ReadMethod[] fnRead;

public InsertLineStreamReader(Stream source, string insertStr, int lineNo) : base( source)
{
this.insertStr = insertStr;
this.lineNo = lineNo;
this.readNo = 0;
this.fnRead = new ReadMethod[] {
new ReadMethod( this.ReadBefore),
new ReadMethod( this.ReadOverflow),
new ReadMethod( this.ReadAfter)
};
this.overflowIndex = 0;
}

//
// . . . Override other methods here (may not be necessary depending on the consumer).
//

public override int Read(char[] buffer, int index, int count)
{
// Use dispatch table of delegates to get the complex override(s)
// out of the way asap.
return this.fnRead[this.readNo](buffer, index, count);
}

public int ReadBefore(char[] buffer, int index, int count)
{
char[] scan = new char[count];
int cchRead = base.Read(scan, 0, count);
if (cchRead > -1)
{
int insOfs, lineCnt = 0;
for (insOfs = 0; insOfs < cchRead && this.lineNo != lineCnt; ++insOfs)
{
if (scan[insOfs] == '\n') ++lineCnt;
}
if (this.lineNo == lineCnt)
{
char[] insertBuf = this.insertStr.ToCharArray( );
if ((insOfs + this.insertStr.Length) > count)
{
int fragmentLen = (insOfs + insertBuf.Length - count);
Array.Copy(scan, 0, buffer, index, insOfs);
Array.Copy(insertBuf, 0, buffer, index + insOfs, fragmentLen);
this.overflow = new char[insertBuf.Length - fragmentLen];
Array.Copy(insertBuf, fragmentLen, this.overflow, 0, this.overflow.Length);
this.readNo = 1;
cchRead = count;
}
else
{
Array.Copy(scan, 0, buffer, index, insOfs);
Array.Copy(insertBuf, 0, buffer, index + insOfs, insertBuf.Length);
int destSpaceRemaining = count - insOfs - insertBuf.Length;
int srcSpaceRemaining = cchRead - insOfs;
if (srcSpaceRemaining > destSpaceRemaining)
{
Array.Copy(scan, insOfs, buffer, index + insOfs + insertBuf.Length, destSpaceRemaining);
this.overflow = new char[srcSpaceRemaining - destSpaceRemaining];
Array.Copy(scan, insOfs + destSpaceRemaining, this.overflow, 0, this.overflow.Length);
this.readNo = 1;
cchRead = count;
}
else
{
Array.Copy(scan, insOfs, buffer, index + insOfs + insertBuf.Length, srcSpaceRemaining);
this.readNo = 2;
cchRead = cchRead + insertBuf.Length;
}
}
}
else
{
Array.Copy(scan, 0, buffer, index, cchRead);
}
}
return cchRead;
}

public int ReadOverflow(char[] buffer, int index, int count)
{
int cchRead;
int overflowLen = this.overflow.Length - this.overflowIndex;

if (count > overflowLen)
{
Array.Copy(this.overflow, this.overflowIndex, buffer, index, overflowLen);
this.overflowIndex = this.overflow.Length;
this.readNo = 2;
cchRead = overflowLen;

int nextCchRead = this.Read( buffer, index + overflowLen, count - overflowLen);
return ( -1 == nextCchRead ) ? cchRead : ( cchRead + nextCchRead );
}

Array.Copy(this.overflow, this.overflowIndex, buffer, index, count);
this.overflowIndex += count;
cchRead = count;
return cchRead;
}

public int ReadAfter(char[] buffer, int index, int count)
{
return base.Read(buffer, index, count);
}
}
}
- - -

Now you might use this to insert an arbitrary line into the beginning of
your XML instance document like this,

FileStream stream = new FileStream("doc.xml", FileMode.Open, FileAccess.Read);
string dtd = "<!-- Ref to your DTD can go here. -->";
InsertLineStreamReader reader = new InsertLineStreamReader(stream, dtd, 1);
XmlValidatingReader xmlReader = new XmlValidatingReader(new XmlTextReader( reader));
// ... wire-up Schema and ValidationEventHandler here.
XmlDocument doc = new XmlDocument( );
doc.Load( xmlReader);

As far as the XmlValidatingReader is concerned, it will receive,

<?xml version="1.0" encoding="UTF-8" ?>
<!-- Ref to your DTD can go here. -->
<XML ... />

even though your file contained,

<?xml version="1.0" encoding="UTF-8" ?>
<XML ... />
Derek Harmon
Nov 12 '05 #2

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

1 post views Thread by Rafaela K. Azinhal | last post: by
2 posts views Thread by Beniamin Tecar | last post: by
4 posts views Thread by Jaime Stuardo | last post: by
reply views Thread by leo001 | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.