2013-02-28 35 views
6

Tôi đã cố xác định và sử dụng các thực thể DTD bên trong App.config. Ví dụ:Tôi có thể khai báo và sử dụng các thực thể DTD trong App.config không?

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE configuration [ 
    <!ENTITY dataSource ".\SQLEXPRESS"> 
]> 
<configuration> 
    <appSettings> 
    <add key="FooDataSource" value="&dataSource;" /> 
    </appSettings> 
    <connectionStrings> 
    <add name="Foo" connectionString="Data Source=&dataSource;;Integrated Security=SSPI;" /> 
    </connectionStrings> 
</configuration> 

Sử dụng System.Configuration.ConfigurationManager để đọc appSettings hoặc connectionStrings sẽ không ném ra một lỗi, nhưng nó cũng không giải quyết được các đối tượng DTD.

(Và đôi khi chương trình sẽ không thực hiện ở tất cả. Tôi không có ý tưởng tại sao NET phàn nàn chỉ thỉnh thoảng của một lỗi cấu hình.)

là sử dụng của tôi của DTD không chính xác, hoặc không .NET không hỗ trợ DTD tùy chỉnh thực thể trong App.config?

Trả lời

4

System.Configuration sử dụng một XmlReaderSettings mặc định để xác định làm thế nào để đọc các tập tin .config. Trong đó có một tài sản ProhibitDtd .Bạn có thể thấy giá trị mặc định của nó với chút mã này:

Console.WriteLine(new XmlReaderSettings().ProhibitDtd); 

Output: True

Vì vậy, đó là một lời giải thích đơn giản tại sao tập tin .config của bạn không hoạt động. Không có cách nào để định cấu hình để ghi đè cài đặt.

Giải thích lý do khiến chương trình của bạn gặp sự cố khi khởi động đòi hỏi nhiều nỗ lực hơn. Lần đầu tiên các tập tin được đọc là rất sớm, trước khi CLR thậm chí bắt đầu. Bootstrapper cần đọc tệp .config để xác định phiên bản của CLR cần tải, phần tử <requestedRuntime> là quan trọng. Nó không sử dụng một trình phân tích cú pháp XML đầy đủ, nó là một phần tử được cắt tỉa gọn gàng có tất cả các bit phân tích cú pháp DTD được loại bỏ. Bạn có thể thấy nó bằng cách tải xuống SSCLI20, trình phân tích cú pháp XML được lưu trữ trong thư mục con clr/src/xmlparser. Chính xác những gì có thể đi sai là không rõ ràng, nhưng nếu phân tích cú pháp có bất kỳ rắc rối với các tập tin .config sau đó bạn sẽ không tìm ra vấn đề có thể được. Điều này xảy ra quá sớm để cho phép bất kỳ chẩn đoán hợp lý nào được tạo ra. Kiểm tra cửa sổ Output cho một số mã thoát có thể đưa ra một gợi ý.

+0

Câu trả lời hay! Xin lỗi vì bình luận vô nghĩa này, nhưng tôi phải đưa cho bạn kudos :) – MetaFight

1

Việc sử dụng pháp nhân của bạn là chính xác; đó là XML được định dạng tốt và không nên có bất kỳ vấn đề nào bằng cách sử dụng tham chiếu thuộc tính trong các thuộc tính.

Nó phải là cái gì đó với .NET * (mà tôi không biết).

Để chứng minh rằng thực thể là đúng, đây là XML của bạn đi qua một bản sắc XSLT chuyển đổi mà giải quyết các đối tượng:

XML Input

<!DOCTYPE configuration [ 
    <!ENTITY dataSource ".\SQLEXPRESS"> 
]> 
<configuration> 
    <appSettings> 
    <add key="FooDataSource" value="&dataSource;" /> 
    </appSettings> 
    <connectionStrings> 
    <add name="Foo" connectionString="Data Source=&dataSource;;Integrated Security=SSPI;" /> 
    </connectionStrings> 
</configuration> 

XSLT

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output indent="yes"/> 
    <xsl:strip-space elements="*"/> 

    <xsl:template match="@*|node()"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()"/> 
     </xsl:copy> 
    </xsl:template> 

</xsl:stylesheet> 

Đầu ra XML

<configuration> 
    <appSettings> 
     <add key="FooDataSource" value=".\SQLEXPRESS"/> 
    </appSettings> 
    <connectionStrings> 
     <add name="Foo" 
      connectionString="Data Source=.\SQLEXPRESS;Integrated Security=SSPI;"/> 
    </connectionStrings> 
</configuration> 

* Dưới đây là một số liên kết Tôi thấy rằng đề cập đến những người khác không có khả năng để có được các đơn vị XML để làm việc:

1

Reflector (trên .NET 4.0) nói rằng System.Configuration.ConfigXmlReader (nội bộ , Đóng dấu) được sử dụng để đọc dữ liệu cấu hình, mà là dựa trên System.Xml.XmlTextReader và gọi đó là nhà xây dựng XmlTextReader(TextReader input), người tạo ra internal XmlTextReaderImpl(TextReader input), và constructor này gọi this(string.Empty, input, new NameTable()) trong đó kêu gọi this(nt) (với chỉ NameTable) mà khởi lĩnh vực tư nhân như this.entityHandling = EntityHandling.ExpandCharEntities;

MSDN says rằng ExpandCharEntities:

Mở rộng đối tượng ký tự và trả về các thực thể chung là Nút EntityReference.

Vì vậy, có vẻ rằng bạn không thể sử dụng các đối tượng của riêng bạn trong tập tin .config :(

Các vấn đề liên quan