【问题标题】:Read XML element with XSD of "anyType" and attribute xsi:type="string"读取 XSD 为“anyType”且属性 xsi:type="string" 的 XML 元素
【发布时间】:2015-10-29 11:50:27
【问题描述】:

我正在尝试读取一个 XML 文档(它是一个 SAML 令牌,但它不是专门与 SAML 相关的问题)。 XSD(请参阅here)在 XSD 的最后 3 行指定 元素,如下所示:

 <element name="AttributeValue" type="anyType" nillable="true"/>

它说它可以是 anyType,这很好。

但实际的 XML 已尝试指定命名空间和类型,而我的 XMLReader 在格式不正确之前正在努力读取它。

<saml:AttributeStatement>
   <saml:Attribute Name="Town">
      <saml:AttributeValue
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:type="string">
                Glasgow
      </saml:AttributeValue>
  </saml:Attribute>
</saml:AttributeStatement>

当我尝试使用此代码读取 XML 时...

//This code just simulates the XmlReader navigating over the document, rather than a specific function.
var sr = new StringReader(xmlString);
var reader = XmlReader.Create(sr);
var output = reader.ReadSubTree();

我收到此错误...

{"ID4254: The AttributeValueXsiType of a SAML Attribute must be a string of the form 'prefix#suffix', where prefix and suffix are non-empty strings.\r\nParameter name: value"}

这是System.IdentityModel.Tokens.SamlAttribute类抛出的,见代码here

我认为是 xsi:type="string" 的格式导致了问题。如果我在 xsi:type="string" 的类型属性中包含 xs:(见下文),它似乎工作正常。

      <saml:AttributeValue
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:type="xs:string">
                Glasgow
      </saml:AttributeValue>
  1. 哪个是有效的 XML? xsi:type="string"xsi:type="xs:string"

  2. 我是否缺少命名空间引用?

(这个XML消息是由第三方生成的,所以我无法更改它,想知道它是否有效)。

更新

根元素确实包含以下命名空间引用:

<Request xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
xmlns="http://thirdparty.co.uk/schema">
  1. 据此推测,默认命名空间是“http://thirdparty.co.uk/schema”??

【问题讨论】:

  • 能否请您发布引发错误的实际代码?目前它无法通过模拟阅读器重现

标签: c# xml saml xmlreader


【解决方案1】:

问题仅在于您使用的类型值的范围。根据您上次有问题的更新,默认架构是http://thirdparty.co.uk/schema

考虑场景:

 <saml:AttributeValue
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:type="string">
                Glasgow
 </saml:AttributeValue>

表示解析器将尝试在默认模式中查找string 类型,当然string 未定义。

现在,当您将其更改为 xs:string 时,意味着您明确告诉在命名空间别名 xs 中查找 string。这就是为什么下面是正确的:

 <saml:AttributeValue
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:type="xs:string">
                Glasgow
 </saml:AttributeValue>

虽然您收到的错误消息是一个验证错误,但可能会应用于严格使用带值的命名空间别名。

【讨论】:

  • 我认为你是对的 - 实际错误是验证错误,而不是 XML 阅读器错误。你会说原来的 xs:type="string" 无效吗?
【解决方案2】:

试试这个

<?xml version="1.0" encoding="utf-8" ?>
<Root xmlns:saml="anything">
<saml:AttributeStatement>
  <saml:Attribute Name="Town">
    <saml:AttributeValue
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:type="string">
      Glasgow
    </saml:AttributeValue>
  </saml:Attribute>
</saml:AttributeStatement>
</Root>​

【讨论】:

  • 我刚刚用根元素上存在的命名空间更新了问题。还有一个进一步的“saml命名空间声明。我相信“字符串”没有前缀,因为它使用'文档的默认命名空间(或本地元素?)?
  • 必须声明每个前缀。 saml 未在您的示例中声明。您可以通过以下方式验证 xml:VS 菜单:项目:添加新项目:XML 文件。将您的 xml 粘贴到窗口中。错误将像任何编译器错误一样显示在错误视图中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多