2012-05-10 22 views
8

Tôi đang thử nghiệm tạo các lớp ràng buộc dữ liệu XML với LinqToXSD và một Lược đồ XML chứa một số lược đồ đã nhập. Tất cả các lược đồ là located here.Làm cách nào để tôi nhận được LinqToXSD để khai báo đúng các khai báo tiền tố không gian tên?

Để thực hiện điều này, tôi đã sử dụng tài liệu giản đồ gốc sau:

<?xml version="1.0" encoding="utf-8"?> 
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:TmatsG="http://www.spiraltechinc.com/tmats/106-13/TmatsG" elementFormDefault="unqualified"> 
    <xs:import namespace="http://www.spiraltechinc.com/tmats/106-13/TmatsCommon" schemaLocation="TmatsCommonTypes.xsd"/> 
    <xs:import namespace="http://www.spiraltechinc.com/tmats/106-13/TmatsC" schemaLocation="TmatsCGroup.xsd"/> 
    <xs:import namespace="http://www.spiraltechinc.com/tmats/106-13/TmatsD" schemaLocation="TmatsDGroup.xsd"/> 
    <xs:import namespace="http://www.spiraltechinc.com/tmats/106-13/TmatsG" schemaLocation="TmatsGGroup.xsd"/> 
    <xs:import namespace="http://www.spiraltechinc.com/tmats/106-13/TmatsH" schemaLocation="TmatsHGroup.xsd"/> 
    <xs:import namespace="http://www.spiraltechinc.com/tmats/106-13/TmatsM" schemaLocation="TmatsMGroup.xsd"/> 
    <xs:import namespace="http://www.spiraltechinc.com/tmats/106-13/TmatsP" schemaLocation="TmatsPGroup.xsd"/> 
    <xs:import namespace="http://www.spiraltechinc.com/tmats/106-13/TmatsR" schemaLocation="TmatsRGroup.xsd"/> 
    <xs:import namespace="http://www.spiraltechinc.com/tmats/106-13/TmatsS" schemaLocation="TmatsSGroup.xsd"/> 
    <xs:import namespace="http://www.spiraltechinc.com/tmats/106-13/TmatsT" schemaLocation="TmatsTGroup.xsd"/> 
    <xs:import namespace="http://www.spiraltechinc.com/tmats/106-13/TmatsV" schemaLocation="TmatsVGroup.xsd"/> 
    <xs:element name="Tmats" type="TmatsG:Tmats"> 
     <xs:annotation> 
      <xs:documentation>Tmats Root</xs:documentation> 
     </xs:annotation> 
    </xs:element> 
</xs:schema> 

Tôi tạo ra các lớp học sử dụng LINQ to XSD. sau đó tôi đã viết bài kiểm tra sau:

[TestMethod()] 
public void TmatsXmlExample4() 
{ 
    Tmats tmats = new Tmats 
    { 
     ProgramName = "My Program", 
     OriginationDate = DateTime.Now, 
    }; 
    tmats.PointOfContact.Add(new PointOfContactType 
    { 
     Address = "12345 Anywhere Street", 
     Agency = "My Agency", 
     Name = "Robert Harvey", 
     Telephone = "111-222-3333" 
    }); 
    Debug.Print(tmats.ToString()); 
} 

tôi mong đợi đầu ra mà nhìn một cái gì đó như thế này:

<Tmats> 
    <TmatsG:ProgramName>My Program</TmatsG:ProgramName> 
    <TmatsG:OriginationDate>2012-05-09-07:00</TmatsG:OriginationDate> 
    <TmatsG:PointOfContact> 
    <TmatsCommon:Name>Robert Harvey</TmatsCommon:Name> 
    <TmatsCommon:Agency>My Agency</TmatsCommon:Agency> 
    <TmatsCommon:Address>12345 Anywhere Street</TmatsCommon:Address> 
    <TmatsCommon:Telephone>111-222-3333</TmatsCommon:Telephone> 
    </TmatsG:PointOfContact> 
</Tmats> 

Thay vào đó, những gì tôi nhận được điều này:

<Tmats> 
    <ProgramName xmlns="http://www.spiraltechinc.com/tmats/106-13/TmatsG">My Program</ProgramName> 
    <OriginationDate xmlns="http://www.spiraltechinc.com/tmats/106-13/TmatsG">2012-05-09-07:00</OriginationDate> 
    <PointOfContact xmlns="http://www.spiraltechinc.com/tmats/106-13/TmatsG"> 
    <Name xmlns="http://www.spiraltechinc.com/tmats/106-13/TmatsCommon">Robert Harvey</Name> 
    <Agency xmlns="http://www.spiraltechinc.com/tmats/106-13/TmatsCommon">My Agency</Agency> 
    <Address xmlns="http://www.spiraltechinc.com/tmats/106-13/TmatsCommon">12345 Anywhere Street</Address> 
    <Telephone xmlns="http://www.spiraltechinc.com/tmats/106-13/TmatsCommon">111-222-3333</Telephone> 
    </PointOfContact> 
</Tmats> 

Có cách nào để có được LinqToXSD để sản xuất sản lượng dự kiến?

+0

Cảm ơn! - Nếu bạn tin tưởng rằng lược đồ không có khả năng thay đổi chúng, bạn có thể chú thích tất cả các phần tử trong tệp 'Tmats.cs' để hỗ trợ trình nối tiếp, nhưng cá nhân tôi chỉ chuyển đổi nó thành một biểu định kiểu và để nó được. –

Trả lời

1

Bạn nên lập bản đồ mỗi schemas nhập khẩu:

<?xml version="1.0"?> 
    <xs:schema 
     xmlns:xs="http://www.w3.org/2001/XMLSchema" 
     xmlns:TmatsCommon="http://www.spiraltechinc.com/tmats/106-13/TmatsCommon" 
     xmlns:TmatsC="http://www.spiraltechinc.com/tmats/106-13/TmatsC" 
     xmlns:TmatsD="http://www.spiraltechinc.com/tmats/106-13/TmatsD" 
     xmlns:TmatsG="http://www.spiraltechinc.com/tmats/106-13/TmatsG" 
     xmlns:TmatsH="http://www.spiraltechinc.com/tmats/106-13/TmatsH" 
     xmlns:TmatsM="http://www.spiraltechinc.com/tmats/106-13/TmatsM" 
     … 
     elementFormDefault="unqualified"> 

elementFormDefault chỉ áp dụng cho các giản đồ rằng nó là trong và nó không ghi đè cài đặt trong bất kỳ bao gồm hoặc nhập khẩu.

Nếu bạn muốn ẩn không gian tên thì tất cả các lược đồ phải chỉ định elementFormDefault = "không đủ tiêu chuẩn". Tương tự, nếu bạn muốn để lộ không gian tên mỗi giản đồ phải ghi rõ elementFormDefault = "có trình độ"

CẬP NHẬT sau khi xem xét kiểm tra đơn vị:

đầu vào của bạn:

<Tmats 
    xmlns:TmatsG="http://www.spiraltechinc.com/tmats/106-13/TmatsG" 
    xmlns:TmatsCommon="http://www.spiraltechinc.com/tmats/106-13/TmatsCommon"> 
    <TmatsG:ProgramName>My Project</TmatsG:ProgramName> 
    <TmatsG:OriginationDate>2012-05-15</TmatsG:OriginationDate> 

Sản lượng của bạn:

<Tmats> 
    <Tmats 
     xmlns:TmatsG="http://www.spiraltechinc.com/tmats/106-13/TmatsG" 
     xmlns:TmatsCommon="http://www.spiraltechinc.com/tmats/106-13/TmatsCommon"> 
     <TmatsG:ProgramName>My Project</TmatsG:ProgramName> 
     <TmatsG:OriginationDate>2012-05-15</TmatsG:OriginationDate> 

Vấn đề nổi bật là sự trùng lặp của thẻ - mọi thứ có vẻ ổn với tôi, vẫn đang vật lộn để hiểu tại sao điều này xảy ra.

CẬP NHẬT Thứ hai:

Tôi nghĩ rằng có một lỗi trong công cụ LinqToXSD - Tôi đã chạy qua mỗi sự kết hợp tôi có thể nghĩ đến và có thể không liên tục làm việc xung quanh vấn đề của bạn, tuy nhiên ... Tôi có quản lý để khắc phục vấn đề <Tmats> trùng lặp:

Trong file XmlHelper của bạn, thay đổi câu lệnh return:

System.Xml.Linq.XDocument xd = System.Xml.Linq.XDocument.Parse(sb.ToString()); 
return xd.Root.FirstNode.ToString(); 

tôi biết đó là một Hack, nhưng nó sửa chữa vấn đề và LoopbackTest của bạn vượt qua.

Bạn không nhận được bất kỳ tiền tố nào nếu bạn tạo các phần tử sử dụng lớp Tmats, tôi đã thử các kết hợp thuộc tính khác nhau và tốt nhất tôi có thể làm là gắn lại các không gian tên. Nếu bạn đang trao đổi thông tin với các hệ thống bên ngoài sau đó tôi có một sửa chữa :

  1. Sử dụng đối tượng Tmats của bạn trong mã của bạn,
  2. Serialize nó với không gian tên,
  3. Run nó thông qua một XSLT để lập bản đồ ns đến tiền tố.

Tôi biết điều đó rất khó, nhưng tôi cho rằng đó là điều tốt nhất bạn nên thực hiện để sửa mã LinqToXSD.

XSLT để lập bản đồ không gian tên với tiền tố (bạn cần phải duy trì các thiết lập của không gian tên trong tuyên bố 'stylesheet' và cũng có trong 'mapper':

<xsl:stylesheet version="2.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:mapper="http://mapper" 
    xmlns:TmatsCommon="http://www.spiraltechinc.com/tmats/106-13/TmatsCommon" 
    xmlns:TmatsC="http://www.spiraltechinc.com/tmats/106-13/TmatsC" 
    xmlns:TmatsD="http://www.spiraltechinc.com/tmats/106-13/TmatsD" 
    xmlns:TmatsG="http://www.spiraltechinc.com/tmats/106-13/TmatsG" 
    xmlns:TmatsH="http://www.spiraltechinc.com/tmats/106-13/TmatsH" 
    xmlns:TmatsM="http://www.spiraltechinc.com/tmats/106-13/TmatsM" 
    xmlns:TmatsP="http://www.spiraltechinc.com/tmats/106-13/TmatsP" 
    xmlns:TmatsR="http://www.spiraltechinc.com/tmats/106-13/TmatsR" 
    xmlns:TmatsS="http://www.spiraltechinc.com/tmats/106-13/TmatsS" 
    xmlns:TmatsT="http://www.spiraltechinc.com/tmats/106-13/TmatsT" 
    xmlns:TmatsV="http://www.spiraltechinc.com/tmats/106-13/TmatsV"> 
    <xsl:output omit-xml-declaration="no" indent="yes"/> 
    <xsl:strip-space elements="*"/> 
    <mapper:namespaces> 
    <ns prefix="TmatsCommon" uri="http://www.spiraltechinc.com/tmats/106-13/TmatsCommon"/> 
    <ns prefix="TmatsC" uri="http://www.spiraltechinc.com/tmats/106-13/TmatsC"/> 
    <ns prefix="TmatsD" uri="http://www.spiraltechinc.com/tmats/106-13/TmatsD"/> 
    <ns prefix="TmatsG" uri="http://www.spiraltechinc.com/tmats/106-13/TmatsG"/> 
    <ns prefix="TmatsH" uri="http://www.spiraltechinc.com/tmats/106-13/TmatsH"/> 
    <ns prefix="TmatsM" uri="http://www.spiraltechinc.com/tmats/106-13/TmatsM"/> 
    <ns prefix="TmatsP" uri="http://www.spiraltechinc.com/tmats/106-13/TmatsP"/> 
    <ns prefix="TmatsR" uri="http://www.spiraltechinc.com/tmats/106-13/TmatsR"/> 
    <ns prefix="TmatsS" uri="http://www.spiraltechinc.com/tmats/106-13/TmatsS"/> 
    <ns prefix="TmatsT" uri="http://www.spiraltechinc.com/tmats/106-13/TmatsT"/> 
    <ns prefix="TmatsV" uri="http://www.spiraltechinc.com/tmats/106-13/TmatsV"/> 
    </mapper:namespaces> 
    <xsl:template match="node()|@*"> 
    <xsl:copy> 
     <xsl:apply-templates select="node()|@*"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="*[namespace-uri()=document('')/*/mapper:namespaces/*/@uri]"> 
    <xsl:variable name="vNS" select="document('')/*/mapper:namespaces/*[@uri=namespace-uri(current())]"/> 
    <xsl:element name="{$vNS/@prefix}:{local-name()}" namespace="{namespace-uri()}" > 
    <xsl:copy-of select="namespace::*[not(. = namespace-uri(current()))]"/> 
    <xsl:copy-of select="@*"/> 
    <xsl:apply-templates/> 
    </xsl:element> 
</xsl:template> 
</xsl:stylesheet> 

Tạo:

<Tmats> 
    <TmatsG:ProgramName xmlns="http://www.spiraltechinc.com/tmats/106-13/TmatsG">My Program</TmatsG:ProgramName> 
    <TmatsG:OriginationDate xmlns="http://www.spiraltechinc.com/tmats/106-13/TmatsG">2012-05-09-07:00</TmatsG:OriginationDate> 
    <TmatsG:PointOfContact xmlns="http://www.spiraltechinc.com/tmats/106-13/TmatsG"> 
    <TmatsCommon:Name xmlns="http://www.spiraltechinc.com/tmats/106-13/TmatsCommon">Robert Harvey</TmatsCommon:Name> 
    <TmatsCommon:Agency xmlns="http://www.spiraltechinc.com/tmats/106-13/TmatsCommon">My Agency</TmatsCommon:Agency> 
    <TmatsCommon:Address xmlns="http://www.spiraltechinc.com/tmats/106-13/TmatsCommon">12345 Anywhere Street</TmatsCommon:Address> 
    <TmatsCommon:Telephone xmlns="http://www.spiraltechinc.com/tmats/106-13/TmatsCommon">111-222-3333</TmatsCommon:Telephone> 
    </TmatsG:PointOfContact> 
</Tmats> 

Ok, do đó, điều này là xa lý tưởng, nhưng mã của bạn hoạt động tốt trong nội bộ dự án chỉ khi bạn cần tương tác với những người khác mà bạn cần sửa chữa đầu ra xml (nhớ thay đổi elementFormDefault = "đủ điều kiện" (hoặc xóa nó) trong yo ur XSD) - nếu bạn lưu trữ XSLT dưới dạng XslCompiledTransform, bạn hầu như không nhận thấy nó xảy ra.

+0

Tôi đã thử điều này, và nó thực sự đã sửa chữa các không gian tên C# được tạo ra bởi LinqToXSD ('Namespace www.spiraltechinc.com.tmats.item106.item13.TmatsC' trở thành' TmatsC' đơn giản), nhưng đầu ra XML đã lưu không thay đổi; nó vẫn có các khai báo xmlns trong mọi phần tử. –

+0

Tôi nghĩ rằng nó có một cái gì đó để làm với ** [this] (http://msdn.microsoft.com/en-us/library/bb387069.aspx) **, nhưng tôi không biết làm thế nào để kết hợp nó vào Các lớp LinqToXSD. –

+0

Tôi phải quay phim để làm việc - nếu bạn có thể đóng gói dự án của bạn và tải nó lên một nơi nào đó, tôi rất vui khi được chơi với nó vào tối nay cho bạn - đó là một vấn đề thú vị. –

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