什么时候检查xmlns?

When do xmlns get checked?

我正在使用 C# XmlSerializer 反序列化其中一部分具有 xmlns 声明的一些 XML(请注意,我 运行 将 CipherValue 设置为适合此 post ):

<EncryptedData
  Id="ZbjUzHbD37LI2DEuiEGX6A7PSnQ+19dutLPiDxZqnFY=3NLz2QA5KCiXVlJSXejhDQ=="
  Type="http://www.w3.org/2001/04/xmlenc#Element" xmlns="http://www.w3.org/2001/04/xmlenc#"
  length="44">
  <EncryptionMethod
    Algorithm="http://www.w3.org/2001/04/xmlenc#aes256-cbc" />
  <CipherData>
    <CipherValue>3NLz2QA5KCiXVlJSXejhDZYYa9sLbv/w42....+PsLMCfRFN//StgbYoRqno3WQ==</CipherValue>
  </CipherData>
</EncryptedData>

将此 XML 加载到 Visual Studio 后,VS 突出显示 Id 属性中的“+”字符,并将长度属性的存在视为错误。我假设 VS 知道这一点的唯一方法是检查 Type 和 xmlns 属性中的 URLs。 VS 发出这种类型的 Internet 请求对我来说没问题,因为我已授予 VS 执行诸如检查更新等操作的权限,所以我已经知道它将按自己的条件访问 Internet。

但是,上述 XML 不会在我的命令行程序中反序列化,除非我删除 xmlns(或通过自定义 XML 文本 Reader 强制空白命名空间),所以我假设我的命令行程序也通过访问 URL.

来验证 xmlns

这对我来说有点麻烦,因为虽然我知道 xmlns URL 是什么,但我没有明确地允许我的程序访问 Internet。此外,该程序的用例是本地运行,并分析由另一个本地唯一程序生成的一些XML。它可以发出 Internet 请求的想法完全不在我的考虑范围之内。

除了反序列化这个 XML,我还在使用 c# XslCompiledTransform class 做一些 XSLT。我最终意识到,在执行转换时,xmlns 属性不是您可以使用 XSLT 操作的东西,因为转换是在 XML 的概念数据上执行的,而不是在原始 XML 上执行的细绳。因此,转换在读取 XML.

时以某种方式处理了 xmlns

我的问题是:

  1. XmlSerializer class 是否与 xmlns 建立隐式 Internet 连接?
  2. XslCompiledTransform class 是否在做类似的事情?
  3. 如果存在隐式连接,它们是否代表安全风险?
  4. 如果是这样,可以采取什么措施来缓解它(除了强制使用空白命名空间之外)?

根据@canton 的要求,这是我用于 EncryptedData 的 class 定义,以及显示引用位置的片段

    ...
    [XmlElement("EncryptedData")]
    public EncryptedData EncryptedData { get; set; }
    ...

    public class EncryptedData
    {
        [XmlAttribute("Id")]
        public string Id { get; set; }

        [XmlAttribute("Type")]
        public string Type { get; set; }

        [XmlAttribute("xmlns")]
        public string Xmlns { get; set; }

        [XmlAttribute("length")]
        public int Length { get; set; }

        [XmlElement("EncryptionMethod")]
        public EncryptionMethod EncryptionMethod { get; set; }

        [XmlElement("CipherData")]
        public CipherData CipherData { get; set; }
   }

首先,命名空间不是 URL!命名空间只是一个任意字符串。它们通常看起来像 URLs 的原因是,如果每个人都在他们拥有或控制的域下使用 URL,那么名称就不会与其他任何人的同名元素发生冲突.即使命名空间为 URL 形式,通常也没有任何实际内容,也没有工具会尝试访问它。

Visual Studio 为所有 Microsoft 和标准模式维护一个模式文件目录。如果你在编辑 XML 时需要智能感知,你可以在那里添加你自己的。检查文档中的位置。

在没有 VS 已知的 xsd 的情况下,VS 或 XmlSerializer 可以理解的唯一属性是 xmlns。

你的反序列化器无法工作的原因是你的元素需要知道命名空间。很容易忽略这一点,因为您在 Internet 上看到的所有示例都倾向于不使用名称空间。

反序列化的一个好方法是使用 xsd.exe 从 xsd 模式或示例数据文件生成 类 - 生成的代码很糟糕但可以指导你在你更漂亮的版本中 - 如果你这样做了,你会看到生成的代码的属性包括一个名称空间,例如

[XmlElement("EncryptedData", Namespace="http://www.w3.org/2001/04/xmlenc#"]

手动创建时,将命名空间放在常量字符串中显然更清晰。

关于什么有和没有命名空间限定符的规则可能会非常混乱,因此我建议先生成示例代码。

如果您确实需要模式验证,则必须通过将验证 XmlReader 传递给 XmlSerializer 自己明确地执行此操作,即验证可以选择作为读取 XML 的一部分而不是反序列化的一部分来完成。