2012-05-10 77 views
8

我正在试验用LinqToXSD创建XML数据绑定类,以及一个包含多个导入模式的XML模式。所有的模式都是located here.如何让LinqToXSD正确输出名称空间前缀声明?

要做到这一点,我用下面的根模式文档:

<?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> 

我创建使用LINQ to XSD类。然后我写了下面的测试:

[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()); 
} 

我期望输出看起来是这样的:

<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> 

相反,我得到的是这样的:

<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> 

有没有一种办法让LinqToXSD产生预期的输出?

+0

谢谢! - 如果你确信模式不可能改变,他们可以注释'Tmats.cs'文件中的所有元素来协助序列化程序,但是我个人只是将它转换为样式表,然后离开它是。 –

回答

1

您应该映射每个导入的模式中:

<?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只适用于它在架构和任何包含或进口不覆盖设置。

如果要隐藏命名空间,则所有模式必须指定elementFormDefault =“不合格”。同样,如果你希望暴露命名空间的每个架构必须指定将elementFormDefault = “合格

审查单元测试之后更新

您的输入:

<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> 

您的输出:

<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> 

突出的问题是标签的重复 - 一切看起来都对我好,仍然努力去理解为什么会发生这种情况。

UPDATE星期一:

我认为这是在LinqToXSD工具的错误 - 我已经通过每一个组合我能想到的,不能始终如一地解决你的问题跑,但是...我设法解决<Tmats>重复问题:

在你XmlHelper文件,更改return语句:

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

我知道这是一个黑客,但它修复了问题并且您的LoopbackTest已通过。

如果创建使用Tmats类元素你没有得到任何前缀,我试过和属性的不同组合,我可以做的是重新连接的命名空间是最好的。如果你是与外部系统交换信息的话,我有一个修复

  1. 使用您的Tmats对象在你的代码,
  2. 与命名空间序列化,通过XSLT映射
  3. 运行它ns作为前缀。

我知道它很笨重,但我认为这是最好的,你会得到实际上修复LinqToXSD代码。

XSLT映射命名空间前缀(你需要保持设定在“样式表”申报命名空间以及在“映射”:

<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> 

产地:

<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> 

好,所以这是很不理想的,但你的代码工作正常,在内部的项目它,只有当你需要与你需要修复的XML输出其他人互动(记得改将elementFormDefault =“合格”(或删除它)在哟你的XSD) - 如果你将XSLT缓存为XslCompiledTransform,你几乎不会注意到它发生了什么。

+0

我尝试这样做,它实际上没有固定正由LinqToXSD生成的古怪底层C#命名空间('命名空间www.spiraltechinc.com.tmats.item106.item13.TmatsC'变得简单地'TmatsC',例如),但保存的XML输出没有改变;它仍然在每个元素中都有xmlns声明。 –

+0

我认为这是与** [这](http://msdn.microsoft.com/en-us/library/bb387069.aspx)**,但我不知道如何将其纳入LinqToXSD类。 –

+0

我得拍客工作 - 如果你能收拾好你的项目,并上传到某个地方,我很高兴在今天晚上晚些时候玩弄它为你 - 这是一个有趣的问题。 –

相关问题