如何让 LinqToXSD 正确输出命名空间前缀声明?

2024-05-16

我正在尝试创建 XML 数据绑定类LinqToXSD http://linqtoxsd.codeplex.com/以及包含许多导入模式的 XML 模式。所有的模式都是位于这里。 http://www.spiraltechinc.com/Tmats/

为了实现此目的,我使用了以下根架构文档:

<?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 产生预期的输出?


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

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

elementForm默认值仅适用于它所在的架构,并且不会覆盖任何包含或导入中的设置。

如果您想隐藏命名空间,那么所有模式都必须指定元素表单默认值=“不合格的".同样,如果您想公开每个模式必须指定的名称空间元素表单默认值=“合格的"

UPDATED查看单元测试后:

您的输入:

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

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

周一更新:

我认为 LinqToXSD 工具中有一个错误 - 我已经运行了我能想到的所有组合,并且无法始终如一地解决您的问题,但是......我已经设法修复了<Tmats>重复问题:

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

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

我知道这是一个hack,但它解决了问题并且您的 LoopbackTest 通过了。

如果使用 Tmats 类创建元素,则不会获得任何前缀,我已经尝试了各种属性组合,我能做的最好的事情就是重新附加命名空间。如果您正在与外部系统交换信息,那么我确实有一个fix:

  1. 在代码中使用 Tmats 对象,
  2. 使用命名空间将其序列化,
  3. 通过 XSLT 运行它以将 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你几乎不会注意到它的发生。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何让 LinqToXSD 正确输出命名空间前缀声明? 的相关文章

  • 以文化中立的方式将字符串拆分为单词

    我提出了下面的方法 旨在将可变长度的文本拆分为单词数组 以进行进一步的全文索引处理 删除停止词 然后进行词干分析 结果似乎不错 但我想听听关于这种实现对于不同语言的文本的可靠性的意见 您会建议使用正则表达式来代替吗 请注意 我选择不使用 S
  • GLKit的GLKMatrix“列专业”如何?

    前提A 当谈论线性存储器中的 列主 矩阵时 列被一个接一个地指定 使得存储器中的前 4 个条目对应于矩阵中的第一列 另一方面 行主 矩阵被理解为依次指定行 以便内存中的前 4 个条目指定矩阵的第一行 A GLKMatrix4看起来像这样 u
  • Web 客户端和 Expect100Continue

    使用 WebClient C NET 时设置 Expect100Continue 的最佳方法是什么 我有下面的代码 我仍然在标题中看到 100 continue 愚蠢的 apache 仍然抱怨 505 错误 string url http
  • 按成员序列化

    我已经实现了template
  • 秒表有最长运行时间吗?

    多久可以Stopwatch在 NET 中运行 如果达到该限制 它会回绕到负数还是从 0 重新开始 Stopwatch Elapsed返回一个TimeSpan From MSDN https learn microsoft com en us
  • 用于检查类是否具有运算符/成员的 C++ 类型特征[重复]

    这个问题在这里已经有答案了 可能的重复 是否可以编写一个 C 模板来检查函数是否存在 https stackoverflow com questions 257288 is it possible to write a c template
  • 为什么当实例化新的游戏对象时,它没有向它们添加标签? [复制]

    这个问题在这里已经有答案了 using System Collections using System Collections Generic using UnityEngine public class Test MonoBehaviou
  • 如何使用 ICU 解析汉字数字字符?

    我正在编写一个使用 ICU 来解析由汉字数字字符组成的 Unicode 字符串的函数 并希望返回该字符串的整数值 五 gt 5 三十一 gt 31 五千九百七十二 gt 5972 我将区域设置设置为 Locale getJapan 并使用
  • OleDbDataAdapter 未填充所有行

    嘿 我正在使用 DataAdapter 读取 Excel 文件并用该数据填充数据表 这是我的查询和连接字符串 private string Query SELECT FROM Sheet1 private string ConnectStr
  • 堆栈溢出:堆栈空间中重复的临时分配?

    struct MemBlock char mem 1024 MemBlock operator const MemBlock b const return MemBlock global void foo int step 0 if ste
  • C++ OpenSSL 导出私钥

    到目前为止 我成功地使用了 SSL 但遇到了令人困惑的障碍 我生成了 RSA 密钥对 之前使用 PEM write bio RSAPrivateKey 来导出它们 然而 手册页声称该格式已经过时 实际上它看起来与通常的 PEM 格式不同 相
  • 带动态元素的 WPF 启动屏幕。如何?

    我是 WPF 新手 我需要一些帮助 我有一个加载缓慢的 WPF 应用程序 因此我显示启动屏幕作为权宜之计 但是 我希望能够在每次运行时更改屏幕 并在文本区域中显示不同的引言 这是一个生产力应用程序 所以我将使用非愚蠢但激励性的引言 当然 如
  • 如何设计以 char* 指针作为类成员变量的类?

    首先我想介绍一下我的情况 我写了一些类 将 char 指针作为私有类成员 而且这个项目有 GUI 所以当单击按钮时 某些函数可能会执行多次 这些类是设计的单班在项目中 但是其中的某些函数可以执行多次 然后我发现我的项目存在内存泄漏 所以我想
  • 垃圾收集器是否在单独的进程中运行?

    垃圾收集器是否在单独的进程中启动 例如 如果我们尝试测量某段代码所花费的进程时间 并且在此期间垃圾收集器开始收集 它会在新进程上启动还是在同一进程中启动 它的工作原理如下吗 Code Process 1 gt Garbage Collect
  • Windows 窗体:如果文本太长,请添加新行到标签

    我正在使用 C 有时 从网络服务返回的文本 我在标签中显示 太长 并且会在表单边缘被截断 如果标签不适合表单 是否有一种简单的方法可以在标签中添加换行符 Thanks 如果您将标签设置为autosize 它会随着您输入的任何文本自动增长 为
  • 对现有视频添加水印

    我正在寻找一种用 C 在视频上加水印的方法 就像在上面写文字一样 图片或文字标签 我该怎么做 谢谢 您可以使用 Nreco 视频转换器 代码看起来像 NReco VideoConverter FFMpegConverter wrap new
  • 通过指向其基址的指针删除 POD 对象是否安全?

    事实上 我正在考虑那些微不足道的可破坏物体 而不仅仅是POD http en wikipedia org wiki Plain old data structure 我不确定 POD 是否可以有基类 当我读到这个解释时is triviall
  • 如何将带有 IP 地址的连接字符串放入 web.config 文件中?

    我们当前在 web config 文件中使用以下连接字符串 add name DBConnectionString connectionString Data Source ourServer Initial Catalog ourDB P
  • C# 成员变量继承

    我对 C 有点陌生 但我在编程方面有相当广泛的背景 我想做的事情 为游戏定义不同的 MapTiles 我已经像这样定义了 MapTile 基类 public class MapTile public Texture2D texture pu
  • 对来自流读取器的过滤数据执行小计

    编辑问题未得到解答 我有一个基于 1 个标准的过滤输出 前 3 个数字是 110 210 或 310 给出 3 个不同的组 从流阅读器控制台 问题已编辑 因为第一个答案是我给出的具体示例的字面解决方案 我使用的实际字符串长度为 450 个

随机推荐