XML Reader관련내용 .NET일반



LINQ to XML떄문에 차후에는 거의 필요없어질 클래스이긴 하지만 내용을 봐두는것도 나쁘지 않을듯

맛배기 -데브피아에서 이상민 님이  올린 코드입니다. 짧지만 좋은 내용인듯.

 1. 읽기

/// <summary>
 /// Class1에 대한 요약 설명입니다.
 /// </summary>
 class XmlReaderClass
 {
  private const string filename = "items.xml";

  /// <summary>
  /// 해당 응용 프로그램의 주 진입점입니다.
  /// </summary>
  [STAThread]
  static void Main(string[] args)
  {
            XmlTextReader reader = null;

   try
   {
    //Load the reader with the data file and ignore all white space nodes.
    reader = new XmlTextReader(filename);
    reader.WhitespaceHandling = WhitespaceHandling.None;

    // Parse the file and display each of the nodes.
    while(reader.Read())
    {
     switch(reader.NodeType)
     {
      case XmlNodeType.Element:
       Console.Write("<{0}>", reader.Name);
       break;
      case XmlNodeType.Text:
       Console.Write(reader.Value);
       break;
      case XmlNodeType.CDATA:
       Console.Write("<![CDATA[{0}]]>", reader.Value);
       break;
      case XmlNodeType.ProcessingInstruction:
       Console.Write("<?{0} {1}?>", reader.Name, reader.Value);
       break;
      case XmlNodeType.Comment:
       Console.Write("<!--{0}-->", reader.Value);
       break;
      case XmlNodeType.XmlDeclaration:
       Console.Write("<?xml version='1.0'?>");
       break;
      case XmlNodeType.DocumentType:
       Console.Write("<!DOCTYPE {0} [{1}]", reader.Name, reader.Value);
       break;
      case XmlNodeType.EntityReference:
       Console.Write(reader.Name);
       break;
      case XmlNodeType.EndElement:
       Console.Write("</{0}>", reader.Name);
       break;
     }
    }
   }
   finally
   {
    if(reader!=null)
     reader.Close();
   }
  }
 }

 

2.쓰기

 public class Sample
 {
  private const string m_Document = "sampledata.xml";
 
  public static void Main()
  {
   XmlTextWriter writer = null;
   XmlTextReader reader = null;
 
   try
   {
    writer = new XmlTextWriter (m_Document, null);
    // Use indenting for readability.
    writer.Formatting = Formatting.Indented;
    writer.Indentation=4;
        
    writer.WriteComment("sample XML fragment");
    
    // Write an element (this one is the root).
    writer.WriteStartElement("book");
 
    // Write the namespace declaration.
    writer.WriteAttributeString("xmlns", "bk", null, "urn:samples");
   
    // Write the genre attribute.
    writer.WriteAttributeString("genre", "novel");
        
    // Write the title.
    writer.WriteStartElement("title");
    writer.WriteString("The Handmaid's Tale");
    writer.WriteEndElement();
              
    // Write the price.
    writer.WriteElementString("price", "19.95");
     
    // Lookup the prefix and write the ISBN element.
    string prefix = writer.LookupPrefix("urn:samples");
    writer.WriteStartElement(prefix, "ISBN", "urn:samples");
    writer.WriteString("1-861003-78");
    writer.WriteEndElement();

    // Write the style element (shows a different way to handle prefixes).
    writer.WriteElementString("style", "urn:samples", "hardcover");
 
    // Write the close tag for the root element.
    writer.WriteEndElement();
             
 
    // Write the XML to file and close the writer.
    writer.Flush();
    writer.Close();
 
 
    // Read the file back in and parse to ensure well formed XML.
    reader = new XmlTextReader (m_Document);
    XmlDocument doc = new XmlDocument();
    // Preserve white space for readability.
    doc.PreserveWhitespace = true;
    //Load the file
    doc.Load(reader);
    
    // Write the XML content to the console.
    Console.Write(doc.OuterXml);
   }

   finally
   {
    Console.WriteLine();
    Console.WriteLine("Processing of the file {0} complete.", m_Document);
    if (reader != null)
     reader.Close();
    if (writer != null)
     writer.Close();
   }
  }
 }   

 

-MSDN정리분

[ XmlReader,XmlTextReader,XmlValidatingReader, XmlNodeReader ]

XmlReader

SAX(Simple API for XML) 판독기와 마찬가지로 XmlReader도 정방향의 읽기 전용 커서, XmlReader 개체는 인코딩되지 않은 데이터를 읽을 수 있다. 즉, 인코딩된데이터는 읽지 못함

XmlTextReader

XmlReader 클래스에서 상속되며 Encoding 속성을 사용하여 인코딩 정보를 제공하며 DTD(문서 형식 정의)를

사용하여 DOCTYPE이 제대로 구성되어 있는지 확인하지만 이를 사용하여 데이터 유효성 검사는 않음.

Normalization 속성에서는 파서가 공백 표준화와 특성 표준화를 수행해야 하는지 여부를 지정, 기본 설정은 false입니다. 이 속성을 false로 설정하면 이 플래그가 숫자 엔터티의 문자 범위 검사까지 해제하므로, XmlTextReader를 통해 문자 엔터티가 &#0;과 같이 나타납니다.

XmlReader를 사용하여 데이터 규칙 검사

     System.Xml.XmlReaderSettings.CheckCharacters 및 System.Xml.XmlReaderSettings.ConformanceLevel 속성을 사용하면 만들어진 XmlReader 개체에서 사용할 규칙 검사의 유형을 지정

     CheckCharacters

- 판독기에서 문자를 검사하고 문자가 유효한 XML 문자 범위 밖에 있을 경우 XmlException을 생성

      - 문서의 모든 문자가 W3C XML 1.0 Recommendation에 정의된 유효한 XML 문자 범위

    - 예) 요소 이름이 숫자로 시작할 경우 XmlException이 발생

    - CheckCharacters 속성을 false로 설정한 경우에도 판독기는 XML 이름이 유효한지는 항상 확인

     ConformanceLevel(Document, Fragment, Auto)

    - 스트림이 특정 규칙 집합을 준수하는지 확인하고 이 규칙 집합을 준수하도록 XmlReader를 구성

    - XML 데이터가 제대로 구성된 XML 1.0 문서 또는 문서 단편에 대한 규칙을 따르는지 여부를 검사

 XmlTextReader, XmlValidatingReader,XmlNodeReader 개체는 Create 메서드를 사용하여 XmlReader 개체를 만들지 않은 경우 가정되는 규칙 수준은 Document입니다. 결과적으로 XmlReader 인스턴스를 다른 XmlReader 개체 안에 래핑하기로 결정한 경우 새 XmlReader 개체를 만들 때 지정된 규칙 수준은 Document 또는 Auto여야 합니다.

XmlParserContext 개체 및 XmlNodeType.Element를 사용하여 기본 XmlTextReader 또는 XmlValidatingReader 개체를 만든 경우 Fragment 설정을 적용할 수도 있습니다.

 -XmlReader 개체를 인스턴스화하려면

XmlReaderSettings settings = new XmlReaderSettings();

settings.ConformanceLevel = ConformanceLevel.Fragment; //단편 수준 규칙

settings.IgnoreWhitespace = true;

settings.IgnoreComments = true;

XmlReader reader = XmlReader.Create("books.xml", settings);

 - XmlDocument에서 XmlNodeReader를 만들려면

XmlDocument doc = new XmlDocument();

doc.Load("MyXml.xml");

XmlNodeReader nodereader = new XmlNodeReader (doc);

while (nodereader.Read()) {

    // Read the XmlDocument as a stream of XML.

}

 - XmlNodeReader는 XmlDocument 내에서 임의의 XmlNode를 사용하여 구성

SelectSingleNode 메서드와 XPath 식을 사용하여 XmlDocument에 있는 특정 노드로 이동합니다. 그런 다음 해당 위치에 XmlNodeReader를 만듭니다. XML 입력 파일인 test.xml에는 다음과 같은 데이터가 들어 있습니다.

<root>

   <child>

      Child Text

   </child>

</root>

 

using System;

using System.Xml;

public class Test {

   public static void Main() {

      XmlDocument doc = new XmlDocument();

      doc.Load("test.xml");

      XmlNode child = doc.SelectSingleNode("/root/child");

      if (child != null) {

         XmlNodeReader nr = new XmlNodeReader(child );

         while (nr.Read() )

            Console.WriteLine( nr.Value );

      }

   }

}

- XmlReader를 이용해서 XmlReader생성(세팅설정)

XmlTextReader txtReader = new XmlTextReader("bookOrder.xml");

XmlReaderSettings settings = new XmlReaderSettings();

settings.Schemas.Add("urn:po-schema", "PO.xsd");

settings.ValidationType = ValidationType.Schema;

XmlReader reader = XmlReader.Create(txtReader, settings);

 - 판독기를 연결한 후에 또다른  설정(setting)을 추가하려면

XmlReaderSettings settings = new XmlReaderSettings();

settings.ValidationType = ValidationType.DTD;

XmlReader inner = XmlReader.Create("book.xml", settings); // DTD Validation

settings.Schemas.Add("urn:book-schema", "book.xsd");

settings.ValidationType = ValidationType.Schema;

XmlReader outer = XmlReader.Create(inner, settings);  // XML Schema Validation

 - XmlSchemaSet을 사용하여 유효성 검사

using System;

using System.Xml;

using System.Xml.Schema;

using System.IO;

 

public class Sample {

 

  public static void Main() {

 

    // Create the XmlSchemaSet class.

    XmlSchemaSet sc = new XmlSchemaSet();

 

    // Add the schema to the collection.

    sc.Add("urn:bookstore-schema", "books.xsd");

 

    // Set the validation settings.

    XmlReaderSettings settings = new XmlReaderSettings();

    settings.ValidationType = ValidationType.Schema;

    settings.Schemas = sc;

    settings.ValidationEventHandler += new ValidationEventHandler (ValidationCallBack);

 

    // Create the XmlReader object.

    XmlReader reader = XmlReader.Create("booksSchemaFail.xml", settings);

 

    // Parse the file.

    while (reader.Read());

   

  }

 

  // Display any validation errors.

  private static void ValidationCallBack(object sender, ValidationEventArgs e) {

    Console.WriteLine("Validation Error: {0}", e.Message);

  }

}

 

booksSchemaFail.xml

<?xml version='1.0'?>

<bookstore xmlns="urn:bookstore-schema">

  <book>

    <author>

      <first-name>Benjamin</first-name>

      <last-name>Franklin</last-name>

    </author>

  </book>

  <book genre="novel">

    <title>The Confidence Man</title>

    <author>

      <first-name>Herman</first-name>

      <last-name>Melville</last-name>

    </author>

    <price>11.99</price>

  </book>

  <book genre="philosophy">

    <title>The Gorgias</title>

    <author>

      <name>Plato</name>

    </author>

    <price>9.99</price>

  </book>

</bookstore>

 

books.xsd

<xsd:schema xmlns:xsd="http://www.w3.org/1001/XMLSchema"

    xmlns="urn:bookstore-schema"

    elementFormDefault="qualified"

    targetNamespace="urn:bookstore-schema">

 

 <xsd:element name="bookstore" type="bookstoreType"/>

 

 <xsd:complexType name="bookstoreType">

  <xsd:sequence maxOccurs="unbounded">

   <xsd:element name="book"  type="bookType"/>

  </xsd:sequence>

 </xsd:complexType>

 

 <xsd:complexType name="bookType">

  <xsd:sequence>

   <xsd:element name="title" type="xsd:string"/>

   <xsd:element name="author" type="authorName"/>

   <xsd:element name="price"  type="xsd:decimal"/>

  </xsd:sequence>

  <xsd:attribute name="genre" type="xsd:string"/>

 </xsd:complexType>

 

 <xsd:complexType name="authorName">

  <xsd:sequence>

   <xsd:element name="first-name"  type="xsd:string"/>

   <xsd:element name="last-name" type="xsd:string"/>

  </xsd:sequence>

 </xsd:complexType>

 

</xsd:schema>

출력

유효성 검사 오류: 네임스페이스 'urn:bookstore-schema'의 요소 'book'이 잘못된 자식 요소 'author'를 가지고 있습니다. 'author' 대신 'title'이 필요합니다.

 

유효성 검사 오류: 네임스페이스 'urn:bookstore-schema'의 요소 'author'가 잘못된 자식 요소 'name'을 가지고 있습니다. 'name' 대신 'first-name'이 필요합니다.

 

 - XmlReader에서 인라인 XML 스키마를 사용하여 유효성 검사

 ProcessInlineSchema 옵션이 활성화되도록 System.Xml.XmlReaderSettings.ValidationFlags 속성을 변경

 인라인 스키마가 루트 요소의 자식 요소로 나타나기 때문에 인라인 스키마 유효성 검사를 수행할 경우 루트 요소의 유효성을 검사할 수 없습니다.

 루트 요소에 대해 유효성 검사 경고가 생성됩니다.

 

using System;

using System.Xml;

using System.Xml.Schema;

using System.IO;

 

public class ValidXSD {

 

  public static void Main() {

 

    // Set the validation settings.

    XmlReaderSettings settings = new XmlReaderSettings();

    settings.ValidationType = ValidationType.Schema;

    settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessInlineSchema;

    settings.ValidationFlags |= XmlSchemaValidationFlags.ReportValidationWarnings;

    settings.ValidationEventHandler += new ValidationEventHandler (ValidationCallBack);

 

    // Create the XmlReader object.

    XmlReader reader = XmlReader.Create("inlineSchema.xml", settings);

 

    // Parse the file.

    while (reader.Read());

   

  }

 

  // Display any warnings or errors.

  private static void ValidationCallBack (object sender, ValidationEventArgs args) {

     if (args.Severity==XmlSeverityType.Warning)

       Console.WriteLine("\tWarning: Matching schema not found.  No validation occurred." + args.Message);

     else

        Console.WriteLine("\tValidation error: " + args.Message);

  } 

}

 

- XmlReader에서 DTD를 사용하여 유효성 검사

using System;

using System.Xml;

using System.Xml.Schema;

using System.IO;

 

public class Sample {

 

  public static void Main() {

 

    // Set the validation settings.

    XmlReaderSettings settings = new XmlReaderSettings();

    settings.ProhibitDtd = false;

    settings.ValidationType = ValidationType.DTD;

    settings.ValidationEventHandler += new ValidationEventHandler (ValidationCallBack);

 

    // Create the XmlReader object.

    XmlReader reader = XmlReader.Create("itemDTD.xml", settings);

 

 

    // Parse the file.

    while (reader.Read());

   

  }

 

  // Display any validation errors.

  private static void ValidationCallBack(object sender, ValidationEventArgs e) {

    Console.WriteLine("Validation Error: {0}", e.Message);

  }

}

 

itemDTD.xml

<!--XML file using a DTD-->

<!DOCTYPE store [

  <!ELEMENT store (item)*>

  <!ELEMENT item (name,dept,price)>

  <!ATTLIST item type CDATA #REQUIRED>

  <!ELEMENT name (#PCDATA)>

  <!ELEMENT price (#PCDATA)>]>

<store>

  <item type="supplies"  ISBN="2-3631-4">

    <name>paint</name>

    <price>16.95</price>

  </item>

</store>

 

 - 래핑된 XmlReader 개체를 사용하여 유효성 검사(XmlNodeReader의 유효성검사)

다른 XmlReader 개체 주위에 래핑된 새 XmlReader 개체를 만들 수 있습니다. 그런 다음 다른 XmlReader 개체 위에 기능을 추가할 수 있습니다.

예를 들어, XmlNodeReader 클래스는 데이터 유효성 검사를 지원하지 않습니다.

XmlNodeReader 개체 주위를 래핑하는 XmlReader 개체를 만들면 XmlNodeReader 개체에 저장된 데이터의 유효성을 검사할 수 있습니다.

using System;

using System.Xml;

using System.Xml.Schema;

using System.IO;

 

public class Sample {

 

  public static void Main() {

 

    // Create and load the XML document.

    XmlDocument doc = new XmlDocument();

    doc.Load("booksSchema.xml");

 

    // Make changes to the document.

    XmlElement book = (XmlElement) doc.DocumentElement.FirstChild;

    book.SetAttribute("publisher", "Worldwide Publishing");

 

    // Create an XmlNodeReader using the XML document.

    XmlNodeReader nodeReader = new XmlNodeReader(doc);

 

    // Set the validation settings on the XmlReaderSettings object.

    XmlReaderSettings settings = new XmlReaderSettings();

    settings.ValidationType = ValidationType.Schema;

    settings.Schemas.Add("urn:bookstore-schema", "books.xsd");

    settings.ValidationEventHandler += new ValidationEventHandler (ValidationCallBack);

 

   // Create a validating reader that wraps the XmlNodeReader object.

   XmlReader reader = XmlReader.Create(nodeReader, settings);

   

   // Parse the XML file.

   while (reader.Read());

  }

 

  // Display any validation errors.

  private static void ValidationCallBack(object sender, ValidationEventArgs e) {

    Console.WriteLine("Validation Error: {0}", e.Message);

  }

}

 

bookSchema.xml

<?xml version='1.0'?>

<bookstore xmlns="urn:bookstore-schema">

  <book genre="autobiography">

    <title>The Autobiography of Benjamin Franklin</title>

    <author>

      <first-name>Benjamin</first-name>

      <last-name>Franklin</last-name>

    </author>

    <price>8.99</price>

  </book>

  <book genre="novel">

    <title>The Confidence Man</title>

    <author>

      <first-name>Herman</first-name>

      <last-name>Melville</last-name>

    </author>

    <price>11.99</price>

  </book>

</bookstore>

 

books.xsd

<xsd:schema xmlns:xsd="http://www.w3.org/1001/XMLSchema"

    xmlns="urn:bookstore-schema"

    elementFormDefault="qualified"

    targetNamespace="urn:bookstore-schema">

 

 <xsd:element name="bookstore" type="bookstoreType"/>

 

 <xsd:complexType name="bookstoreType">

  <xsd:sequence maxOccurs="unbounded">

   <xsd:element name="book"  type="bookType"/>

  </xsd:sequence>

 </xsd:complexType>

 

 <xsd:complexType name="bookType">

  <xsd:sequence>

   <xsd:element name="title" type="xsd:string"/>

   <xsd:element name="author" type="authorName"/>

   <xsd:element name="price"  type="xsd:decimal"/>

  </xsd:sequence>

  <xsd:attribute name="genre" type="xsd:string"/>

 </xsd:complexType>

 

 <xsd:complexType name="authorName">

  <xsd:sequence>

   <xsd:element name="first-name"  type="xsd:string"/>

   <xsd:element name="last-name" type="xsd:string"/>

  </xsd:sequence>

 </xsd:complexType>

 

</xsd:schema>

 

출력

유효성 검사 오류: 'publisher' 특성이 선언되지 않았습니다.

 

-요소 읽기

IsStartElement : 현재 노드가 시작 태그인지 또는 빈 요소 태그인지 확인합니다.

ReadStartElement : 현재 노드가 요소인지 확인하고 판독기를 다음 노드로 진행합니다.

ReadEndElement : 현재 노드가 끝 태그인지 확인하고 판독기를 다음 노드로 진행합니다.

ReadElementString :  텍스트 전용 요소를 읽습니다.

ReadToDescendant : XmlReader를 지정된 이름의 다음 하위 요소로 진행합니다.

ReadToNextSibling :  XmlReader를 지정된 이름의 다음 형제 요소로 진행합니다.

IsEmptyElement : 재 요소에 빈 요소 태그가 있는지 확인합니다.

  <item num="123"/>(IsEmptyElement가 true임)

  <item num="123">(요소 내용이 비어 있더라도 IsEmptyElement가 false임)

  즉, IsEmptyElement는 소스 문서의 요소에 끝 요소 태그가 있는지 여부를 보고합니다.

 

다음 코드는 ReadStartElement 및 ReadString 메서드를 사용하여 요소를 읽습니다.

using (XmlReader reader = XmlReader.Create("book3.xml")) {

 

  // Parse the XML document.  ReadString is used to

  // read the text content of the elements.

  reader.Read();

  reader.ReadStartElement("book"); 

  reader.ReadStartElement("title");  

  Console.Write("The content of the title element:  ");

  Console.WriteLine(reader.ReadString());

  reader.ReadEndElement();

  reader.ReadStartElement("price");

  Console.Write("The content of the price element:  ");

  Console.WriteLine(reader.ReadString());

  reader.ReadEndElement();

  reader.ReadEndElement();

 

}

 

while (reader.Read()) {

  if (reader.IsStartElement()) {

    if (reader.IsEmptyElement)

      Console.WriteLine("<{0}/>", reader.Name);

    else {

      Console.Write("<{0}> ", reader.Name);

      reader.Read(); // Read the start tag.

      if (reader.IsStartElement())  // Handle nested elements.

        Console.Write("\r\n<{0}>", reader.Name);

      Console.WriteLine(reader.ReadString());  //Read the text content of the element.

    }

  }

}

 

- 특성(attribute) 읽기

AttributeCount 속성을 사용하여 요소에 있는 모든 특성을 읽습니다.

if (reader.HasAttributes) {

  Console.WriteLine("Attributes of <" + reader.Name + ">");

  for (int i = 0; i < reader.AttributeCount; i++) {

    Console.WriteLine("  {0}", reader[i]);

  }

  // Move the reader back to the element node.

  reader.MoveToElement();

}

While 루프에 MoveToNextAttribute 메서드를 사용하여 요소에 있는 모든 특성을 읽습니다.

if (reader.HasAttributes) {

  Console.WriteLine("Attributes of <" + reader.Name + ">");

  while (reader.MoveToNextAttribute()) {

    Console.WriteLine(" {0}={1}", reader.Name, reader.Value);

  }

  // Move the reader back to the element node.

  reader.MoveToElement();

}

이름으로 특성 값을 얻습니다.

reader.ReadToFollowing("book");

string isbn = reader.GetAttribute("ISBN");

Console.WriteLine("The ISBN value: " + isbn);

 

- 내용 읽기

XmlReader 클래스에는 내용을 읽는 데 사용할 수 있는 멤버들

Value 속성(노드 형식 : 값 )

 Attribute :  특성 값입니다.

 CDATA CDATA : 섹션 내용입니다.

 Comment : 주석의 내용입니다.

 DocumentType : 내부 하위 집합입니다.

 ProcessingInstruction : 대상을 제외한 전체 내용입니다.

 SignificantWhitespace : 혼합 내용 모델에서 태그 사이의 공백입니다.

 Text : 텍스트 노드의 내용입니다.

 Whitespace : 태그 사이의 공백입니다.

 XmlDeclaration : 선언 내용입니다.

 기타 모든 노드 : 형식 빈 문자열입니다.

ReadString,ReadInnerXmlReadOuterXml 메서드

 

- 형식화된 데이터 읽기

ReadContentAs 메서드를 사용하여 텍스트 내용을 읽고 지정된 형식의 개체를 반환할 수 있습니다.

ReadContentAsBoolean, ReadContentAsDateTime, ReadContentAsDouble, ReadContentAsLong, ReadContentAsInt,ReadContentAsString

메서드를 사용하여 특정 CLR 개체를 반환할 수 있습니다

ReadContentAsObject 메서드는 ValueType 속성에서 지정하는 가장 적절한 유형의 boxed CLR을 반환합니다.

형식화되지 않은 내용의 경우 판독기가 해당 내용을 문자열로 반환합니다.

using (XmlReader reader = XmlReader.Create("dataFile_2.xml")) {

      reader.ReadToDescendant("item");

      do {

          reader.MoveToAttribute("sale-item");

          Boolean onSale = reader.ReadContentAsBoolean();

          if (onSale) {

             Console.WriteLine(reader["productID"]);

          }

      } while (reader.ReadToNextSibling("item"));   

}

dataFile_2.xml

<root>

  <item sale-item='true' productID='123456' colors='blue green black'>

    <price>9.95</price>

  </item>

  <item sale-item='false' productID='124390'>

    <price>5.95</price>

  </item>

  <item sale-item='true' productID='53298'>

    <price>12.95</price>

  </item>

</root>

 

- 형식화된 요소 내용
ReadElementContentAs 메서드를 사용하여 요소 내용을 읽고 지정된 형식의 개체를 반환할 수 있습니다.

ReadElementContentAsBoolean, ReadElementContentAsDateTime, ReadElementContentAsDouble, ReadElementContentAsLong, ReadElementContentAsInt,ReadElementContentAsString

메서드는 요소 내용을 읽고 특정 CLR 개체를 반환합니다.

ReadElementContentAsObject 메서드는 ValueType 속성에서 지정하는 가장 적절한 유형의 boxed CLR을 반환합니다

 

 

using (XmlReader reader = XmlReader.Create("dataFile.xml"))

{

     reader.ReadToFollowing("stringValue");

     Console.WriteLine(reader.ReadElementContentAsString());           

}

dataFile.xml

<root>

  <stringValue>

     <!--comment-->

     <?some pi?>

      text value of the element.

  </stringValue>

  <longValue>270000000000001</longValue>

  <number>0</number>

  <double>2E10</double>

  <date>2003-01-08T15:00:00-00:00</date>

</root>

 

- XmlTextReader를 사용하여 XML 단편 읽기

XmlParserContext 클래스는 XML 단편 또는 문서를 구문 분석하는 데 필요한 컨텍스트 정보로 XmlTextReader 개체를 구성하는 데 사용됩니다.

XmlParserContext 클래스에서는 사용할 XmlNameTable, 네임스페이스 범위, 현재 xml:lang 및 xml:space 범위 같은 정보를 제공할 수 있습니다.

 

XmlTextReader tr = new XmlTextReader("<element1> abc </element1>

  <element2> qrt </element2>

  <?pi asldfjsd ?>

  <!-- comment -->", XmlNodeType.Element, null);  // null로 준 예제를 왜 넣어놨지??

while(tr.Read())

    Console.WriteLine("NodeType: {0} NodeName: {1}", tr.NodeType, tr.Name);

참고>

XmlDocument 및 XmlReader 같은 일부 클래스에서는 XmlNameTable 클래스를 내부적으로 사용하여 특성과 요소 이름을 저장합니다.

XML 문서에서 요소나 특성 이름이 여러 번 나오더라도 XmlNameTable에는 한 번만 저장됩니다.

이름은 CLR(공용 언어 런타임) 개체 형식으로 저장됩니다. 그러면 더 비용이 많이 드는 문자열 비교를 하지 않고 이 문자열에 대해 개체 비교를 할 수 있습니다.

이러한 문자열 개체를 atomizedstrings라고 합니다.

XmlNameTable는 NameTable 클래스에 구현됩니다.

NameTable nt = new NameTable();

object book = nt.Add("book");

object title = nt.Add("title");

 

 // Create a reader that uses the NameTable.

 XmlReaderSettings settings = new XmlReaderSettings();

 settings.NameTable = nt;

 XmlReader reader = XmlReader.Create("books.xml", settings);

 

 while (reader.Read()) {

    if (reader.NodeType == XmlNodeType.Element) {

      // Cache the local name to prevent multiple calls to the LocalName property.

      object localname = reader.LocalName;

 

      // Do a comparison between the object references. This just compares pointers.

      if (book == localname) {

          // Add additional processing here.

      }

      // Do a comparison between the object references. This just compares pointers.

      if (title == localname) {

         // Add additional processing here.

      }

        

    }

 

 }  // End While

 

// Close the reader.

reader.Close();    

 

- XmlTextReader를 사용하여 공백 처리

유효 공백

DTD(문서 형식 정의)로 정의된 혼합 내용 모델 내의 공백이거나 xml:space가 "preserve"로 설정되어 있을 때 특수한 특성 xml:space의 범위 내에 있는 공백.

??????

  

- XmlValidatingReader를 사용하여 XML 단편 읽기

- XmlValidatingReader를 사용하여 XML 단편을 읽고 콘솔에 기록합니다

using System;

using System.Xml;

 

public class Sample

{

  public static void Main (String[] args)

  {

    XmlValidatingReader vr = new XmlValidatingReader("<element1> abc </element1>  <element2> qrt </element2> <?pi asldfjsd ?> <!-- comment -->", XmlNodeType.Element, null);

    while(vr.Read())

      Console.WriteLine("NodeType: {0} NodeName: {1}", vr.NodeType, vr.Name);

   }

}

 

-  XmlNamespaceManager에서 필요한 네임스페이스를 제공하기 위해 XmlParserContext를 사용하는 XML 단편을 읽습니다.

using System;

using System.IO;

using System.Xml;

 

public class Sample

{

  public static void Main()

  {

 

      string xmlFrag = "<book><bk:genre>&n;</bk:genre></book>";

      NameTable nt = new NameTable();

      XmlNamespaceManager nsmanager = new XmlNamespaceManager(nt);

     // Add a default namespace.

     nsmanager.AddNamespace (string.Empty, "www.microsoft.com");

     nsmanager.AddNamespace ("bk", "www.microsoft.com/books");

     string internalContent = "<!ENTITY n 'novel'>";

     XmlParserContext context = new XmlParserContext(nt, nsmanager, "elem",null, null, internalContent, string.Empty,

string.Empty, XmlSpace.None);

     XmlValidatingReader r = new XmlValidatingReader(xmlFrag, XmlNodeType.Element, context);

     r.ValidationType = ValidationType.None;

     r.EntityHandling = EntityHandling.ExpandEntities;

     while(r.Read())

        Console.WriteLine("{0},{1},{2}",r.NodeType, r.Name, r.Value);

 

  }

}

  

- XPathDocument 및 XmlDocument를 사용하여 XML 데이터 읽기

- System.Xml.XPath : 읽기 전용 XPathDocument 클래스를 사용하여 XML 문서를 읽음

XPathDocument 클래스는 XPath 데이터 모델을 사용하여 빠른 속도의 읽기 전용 메모리 내장 XML 문서 표현을 제공합니다.

6개 생성자 중 하나를 사용하여 XPathDocument 클래스의 인스턴스가 생성됩니다.

이러한 생성자를 사용하면 XML 파일에 대한 string 경로뿐 아니라 Stream, TextReader 또는 XmlReader 개체를 사용하여 XML 문서를 읽을 수 있습니다.

 

- System.Xml : 에서 편집 가능한 XmlDocument 클래스를 사용하여 XML 문서를 읽는 것입니다.

XmlDocument 클래스는 W3C DOM(문서 개체 모델) Level 1 Core 및 Core DOM Level 2를 구현하는 XML 문서의 편집 가능한 메모리 내장 표현입니다.

세 가지 생성자 중 하나를 사용하여 XmlDocument 클래스의 인스턴스가 생성됩니다.

매개 변수 없이 XmlDocument 클래스 생성자를 호출하여 비어 있는 새 XmlDocument 개체를 만들 수 있습니다.

생성자를 호출한 후 Load 메서드를 사용하여 XML 파일의 string 경로뿐 아니라 Stream, TextReader 또는 XmlReader 개체에서 새 XmlDocument 개체로 XML 데이터를 로드합니다.

XmlDocument document = new XmlDocument();

document.Load("books.xml");

 

XmlTextReader 클래스는 XmlReader 클래스에서 상속되며 Encoding 속성을 사용하여 인코딩 정보를 제공합니다.

또한 XPathDocument 개체 또는 XmlDocument 개체를 만드는 데 사용할 수도 있습니다.

XPathDocument 또는 XmlDocument 개체로 XML 문서를 읽어온 후 XPathNavigator 개체를 만들어 기본 XML 데이터를 선택, 평가 및 탐색할 수 있으며 일부 경우에 편집할 수도 있습니다.

XmlNode,XPathDocument,XmlDocument 클래스는 System.Xml.XPath 네임스페이스의 IXPathNavigable 인터페이스를 구현합니다. 결과적으로 세 클래스는 모두 XPathNavigator 개체를 반환하는 CreateNavigator 메서드를 제공합니다.

 

- 문자 스트림을 사용하여 대용량 스트림 읽기

System.Xml.XmlTextReader.ReadChars(System.Char[],System.Int32,System.Int32), System.Xml.XmlTextReader.ReadBinHex(System.Byte[],System.Int32,System.Int32)

System.Xml.XmlTextReader.ReadBase64(System.Byte[],System.Int32,System.Int32)

두 메서드는 대용량 스트림을 읽는 데 사용됩니다.

ReadChars 메서드는 텍스트를 있는 그대로 읽고(US-ASCII)

ReadBase64 메서드는 Base64로 인코딩된 텍스트를 디코딩

ReadBinHex 메서드는 binhex로 인코딩된 데이터를 디코딩, XML에 포함 문서, 이미지 또는 인코딩된 비디오가 들어 있는 경우에 유용합니다.

ReadChars, ReadBinHex 및 ReadBase64는 요소에서만 사용가능

ReadChars 메서드는 작동하던 문자 스트림의 끝에 도달하면 "0"을 반환,판독기 위치는 ReadInnerXml을 호출했을 때의 위치와 동일.

ReadAttributeValue와 같은 모든 특성 Read 메서드는 ReadChars를 사용하여 스트림에서 읽는 동안 아무런 동작을 수행하지 않습니다.

 

- ReadBase64의 샘플 코드

string str = "<ROOT>AQID</ROOT>";

XmlTextReader r = new XmlTextReader(new StringReader(str));

 

r.Read();

byte[] buffer = new byte[1];

while(r.ReadBase64(buffer,0,1) != 0) {

   Console.Write(buffer[0]);

}

Console.WriteLine();

  

- ReadBinHex의 샘플 코드

private void TestIncrementalReadBinHex() {      

   XmlTextReader xmlReader   = new XmlTextReader("wellform.xml");

   try {

      int binhexlen = 0;

      byte[] binhex = new byte[1000];

      while (xmlReader.Read()) {

         if ("dt:BinHex" == xmlReader.Name) break;

      }

      binhexlen = xmlReader.ReadBinHex(binhex, 0, 50);

      for (int i=0; i < binhexlen; i++) Console.Write(binhex[i]);

      while ("dt:BinHex" == xmlReader.Name) {

         binhexlen = xmlReader.ReadBinHex(binhex, 0, 50);

         for (int i=0; i < binhexlen; i++) Console.Write(binhex[i]);

      }

      Console.WriteLine();

      xmlReader.Close();

   }

   catch(Exception e) {

      xmlReader.Close();

      Console.WriteLine("Exception: " + e.Message);

      return;

   }

}

wellform.xml

<dt:person xmlns:dt="urn1">

<name>Alice Smith</name>

<dt:address>123 Maple Street, Seattle, WA 98112</dt:address>

<phone>(206) 555-0104</phone>

<!-- The following element is optional -->

<comments>The lady with the overgrown lawn.</comments>

<dt:date>2000-07-06</dt:date>

<time>18:31:40</time>

<dt:BinHex>000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF</dt:BinHex>

<Base64>AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn+AgYKDhIWGh4iJiouMjY6PkJGSk5SVlpeYmZqbnJ2en6ChoqOkpaanqKmqq6ytrq+wsbKztLW2t7i5uru8vb6/wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX2Nna29zd3t/g4eLj5OXm5+jp6uvs7e7v8PHy8/T19vf4+fr7/P3+/w==</Base64>

</dt:person>

 

- ReadChars의 샘플

 ...

<small>

   <time>

      <days> 30 </days>

      <hours> 3 </hours>

      <minutes> 30 </minutes>

   </time>

</small>

<big>

...

위의 XML 입력에 대해 다음 코드를 실행하면 응용 프로그램이 while 루프에 있을 때 현재 위치는 <small> 태그가 되며, 이 루프 끝에 있을 때 현재 위치는 <big> 태그가 된다는 것을 알 수 있습니다.

if (XmlNodeType.Element == reader.NodeType && "small" == reader.Name) {

    while(0 != reader.ReadChars(buffer, 0, 1)) {

        // Do something;

        // reader is now positioned at <small>. Attribute values may not

       // be available at this point.

    }

}

// At this point the Reader is positioned at <big > tag.

ReadChars의 끝까지 계속해서 읽지 않으려면, 중간에 Read 메서드를 호출하여 판독기를 끝 요소 뒤에 위치시킬 수 있습니다.

앞의 코드에서 이 위치는 <big> 태그가 될 것입니다.

첫 번째 호출: ReadChars(buf, 0, 2) : 2가 반환되며 buf에는 "te"가 포함됩니다.

두 번째 호출: ReadChars(buf, 0, 2) : 2가 반환되며 buf에는 "st"가 포함됩니다.

세 번째 호출: ReadChars(buf, 0, 2) : 0이 반환됩니다.

 

 - 다음 예제에서는 Base64와 BinHex 데이터가 포함된 파일을 읽습니다.

using System;

using System.IO;

using System.Xml;

 

public class Sample {

 

  private const string filename = "binary.xml";

 

  public static void Main() {

 

     XmlTextReader reader = null;

 

     try {

    

        reader = new XmlTextReader(filename);

        reader.WhitespaceHandling = WhitespaceHandling.None;

 

        // Read the file. Stop at the Base64 element.

        while (reader.Read()) {

           if ("Base64" == reader.Name) break;

        }

             

        // Read the Base64 data. Write the decoded

        // bytes to the console.

        Console.WriteLine("Reading Base64... ");

        int base64len = 0;

        byte[] base64 = new byte[1000];

        do {

           base64len = reader.ReadBase64(base64, 0, 50);           

           for (int i=0; i < base64len; i++) Console.Write(base64[i]);

        } while (reader.Name == "Base64");

    

        // Read the BinHex data. Write the decoded

        // bytes to the console.

        Console.WriteLine("\r\nReading BinHex...");

        int binhexlen = 0;

        byte[] binhex = new byte[1000];

        do {

           binhexlen = reader.ReadBinHex(binhex, 0, 50);           

           for (int i=0; i < binhexlen; i++) Console.Write(binhex[i]);

        }  while (reader.Name == "BinHex");

           

     }

 

     finally {

        Console.WriteLine();

        Console.WriteLine("Processing of the file {0} complete.", filename);

        if (reader != null)

          reader.Close();

     }

  }

}

 

binary.xml

<data>

<!-- sample data for base64 and binhex -->

<Base64>AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS

4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFi

Y2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6e3x9fn+AgYKDhIWGh4iJiouMjY6PkJGSk5SVlp

eYmZqbnJ2en6ChoqOkpaanqKmqq6ytrq+wsbKztLW2t7i5uru8vb6/wMHCw8TFxsfIycrL

zM3Oz9DR0tPU1dbX2Nna29zd3t/g4eLj5OXm5+jp6uvs7e7v8PHy8/T19vf4+fr7/P3+/w

==</Base64>

<BinHex>000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E

1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F4041

42434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F6061626364

65666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F8081828384858687

88898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AA

ABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCD

CECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0

F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF</BinHex>

</data>

 

 - XML 파일을 데이터 집합으로 읽어 오기

dataSet1.ReadXml(folder & "\dataset.xml")

- 파일에서 읽을 때 XmlResolver에 인증 자격 증명 제공

읽으려는 XML 데이터가 포함된 파일의 URL을 확인하려는 경우 이 파일에 제한된 액세스 정책이 있을 수 있습니다.

네트워크 리소스에 액세스하기 위해 인증이 필요한 경우 Credentials 속성을 사용하여 필요한 자격 증명을 지정합니다.

Credentials 속성을 설정하지 않으면 자격 증명은 null로 설정됩니다

 

예를 들어, 웹에서 데이터를 요청할 때 인증을 위한 자격 증명이 필요하다고 가정하겠습니다.

웹 가상 디렉터리에서 익명 액세스를 허용하는 경우에는 이 속성을 익명 액세스로 설정할 필요가 없습니다.

그러나 해당 디렉터리에서 익명 액세스를 허용하지 않는 경우 자격 증명을 제공해야 합니다.

다음 예제에서는 기본 자격 증명과 함께 XmlUrlResolver를 사용하는 XmlReader를 만들어 http://localhost/bookstore/inventory.xml 사이트에 액세스합니다.

// Create a resolver with default credentials.

XmlUrlResolver resolver = new XmlUrlResolver();

resolver.Credentials = System.Net.CredentialCache.DefaultCredentials;

 

// Set the reader settings object to use the resolver.

settings.XmlResolver = resolver;

 

// Create the XmlReader object.

XmlReader reader = XmlReader.Create("http://ServerName/data/books.xml", settings);

 

URI가 서로 다른 경우 다른 자격 증명을 제공할 수 있으며 서로 다른 자격 증명을 자격 증명 캐시에 추가할 수 있습니다.

이러한 자격 증명은 XML의 원본 소스와는 무관하게 서로 다른 URI의 인증을 검사하는 데 사용됩니다.

다음 예제는 자격 증명을 캐시에 추가하는 방법을 보여 줍니다.

// Create the credentials.

NetworkCredential myCred = new NetworkCredential(UserName,SecurelyStoredPassword,Domain);

CredentialCache myCache = new CredentialCache();

myCache.Add(new Uri("http://www.contoso.com/"), "Basic", myCred);

myCache.Add(new Uri("http://app.contoso.com/"), "Basic", myCred);

 

// Set the credentials on the XmlUrlResolver object.

XmlUrlResolver resolver = new XmlUrlResolver();

resolver.Credentials = myCache;

 

// Compile the style sheet.

XslCompiledTransform xslt = new XslCompiledTransform();

xslt.Load("http://serverName/data/xsl/order.xsl",XsltSettings.Default, resolver);

 

 - XmlTextReader에서 XmlException을 사용하여 예외 처리

XmlException 클래스는 XmlTextReader 클래스와 함께 사용되어 구문 분석 중에 발생하는 구문 오류에서 데이터 오류를 캐치합니다.

오류가 캐치되는 원인은 데이터를 구성하는 방법에 문제가 있었기 때문입니다.

데이터는 W3C(World Wide Web 컨소시엄) 권장 사항에서 정의된 규칙에 따라 구성되어야 합니다.

 

- 다음 코드 예제에서 XmlException 클래스는 LineNumber.xml 문서에서 발생한 오류의 LineNumber, LinePosition 및 소스 URI를 반환합니다.

  오류의 원인은 LineNumber.xml 문서에서 XML이 제대로 구성되지 않았기 때문입니다.

XmlTextReader tr = new XmlTextReader("LineNumber.xml");

XmlValidatingReader r = new XmlValidatingReader(tr);

r.ValidationType = ValidationType.None;

try {

   while(r.Read());

}

catch(XmlException e) {

   Console.WriteLine(e.Message);

   Console.WriteLine("Exception object Line, pos: (" + e.LineNumber + "," + e.LinePosition  + ")");

   Console.WriteLine("Exception source URI: (" + e.SourceURI + ")");

   Console.WriteLine("XmlReader Line, pos: (" + tr.LineNumber + "," + tr.LinePosition  + ")");

}


덧글

※ 로그인 사용자만 덧글을 남길 수 있습니다.


구글광고