亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

PHP xmllib XSD 驗證命名空間錯誤:沒想到 X,預期 X

PHP xmllib XSD 驗證命名空間錯誤:沒想到 X,預期 X

PHP
慕沐林林 2023-07-08 20:39:29
我一直在嘗試讓 xmllib 通過 合作并驗證 xmldsig<Signature>元素DOMDocument,但無論我如何將元素扔給它,它都會不斷產生虛假錯誤。顯然,由于而無法<Signature>成為 root 。我無法正確設置根上的屬性:嘗試驗證結果:DOMDocumentxmlnsElement 'Signature': No matching global declaration available for the validation root. 我認為這可能是因為模式旨在“包含”,您畢竟想要簽署“某些東西”,而不僅僅是本身簽名。因此,通過創建這個:<?xml version="1.0"?><xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"    xmlns:ds="http://www.w3.org/2000/09/xmldsig#"    version="1.0"    elementFormDefault="qualified"><xs:import namespace="http://www.w3.org/2000/09/xmldsig#" schemaLocation="xmldsig-core-schema.xsd" /><xs:element name="root">    <xs:complexType>        <xs:sequence>            <xs:element ref="ds:Signature" />        </xs:sequence>    </xs:complexType></xs:element></xs:schema>我現在可以擁有虛擬元素的包含簽名。我意識到 PHP XML 處理相當糟糕,沒有一個工具真正工作得那么好。然而,一旦它實際上正確地將事情交給 xmllint,這樣做應該沒有問題。其他答案建議也添加 XPath,但我想保持 KISS;盡可能少地使用 PHP 庫。通過幾百行代碼的欺騙,我讓它配合并將<Signature>xml 文件的一部分包裝到一個<root>元素內的普通測試文件中。我認為它正在做一些事情來破壞文檔中的名稱空間。$myDocument->saveXML();失敗后調用$myDocument->schemaValidate();會返回一個特殊的結果:Element 'Signature': This element is not expected. Expected is ( {http://www.w3.org/2000/09/xmldsig#}Signature ).當 xml 看起來像這樣時(我已經添加了格式;實際情況是未格式化的;盡管空格不應該很重要):<?xml version="1.0"?><root>    <Signature xmlns="http://www.w3.org/2000/09/xmldsig#">         (... omitted crypto ...)    </Signature></root>從我對它所做的閱讀來看,該錯誤應該意味著<Signature> 元素上的命名空間是錯誤的。但在這里,它明確地明確指定為xmlns錯誤消息所期望的內容。那么,這里出了什么問題呢?附錄:準備簽名進行驗證的代碼(在任意文檔中)看起來像這樣。這是一個復雜的版本,我添加了一個“根”元素,而不是直接使用模式,請參閱下面的我的答案,結果證明這是不必要的,盡管這是一個很好的測試,就像在您想要的更復雜的場景中一樣要在對 libxml 的一次調用中驗證簽名的內容,這是一件有效的事情:
查看完整描述

1 回答

?
MM們

TA貢獻1886條經驗 獲得超2個贊

PHP 就是問題所在。它存在微妙的錯誤,并且不會/不能正確理解以編程方式創建的文檔中的 XML 名稱空間。

添加/編輯 DOMDocument 元素的方法有多種,其中一些/大部分可能會導致元素E位于某個名稱空間X中,當您僅查看 XML 輸出時,但 DOMDocument 對象認為它位于名稱空間Y中。即使您只使用提供的函數而不訪問對象的內部,也可能使它們處于不一致的狀態。在某些情況下,如果您想要特定格式的命名空間(由于規范化問題)甚至是不可避免的。

替換該行代碼

$myDocument->schemaValidate();

$myDocument->loadXML($myDocument->saveXML());
$myDocument->schemaValidate();

并且驗證錯誤應該消失。無論哪種方式(使用xsd包含的自定義或直接使用 xmldsig 驗證文件)都應該有效。

雖然該錯誤被視為“不是錯誤”,但它確實是一個問題,因為DOMDOcument實際上不會使用xmlns屬性輸出確切的語法,而是使用前綴表示法(如果您使用createElementNS().?(雖然語法上可能是相同的,但沒有人理解 xml 命名空間,因此接受您的 XML 的人可能希望它與示例完全相同,即:使用 ,而xmlns不是使用元素ds:Signature)。

相反, usingDOMElement::setAttributeNS($currentNS, 'xmlns', $subElementNS)?輸出默認命名空間標記,但不會使用新命名空間正確遞歸地標記元素下的編程實體。


查看完整回答
反對 回復 2023-07-08
  • 1 回答
  • 0 關注
  • 129 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號