我从外部服务收到了这些xml:
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href=(...)?>
<pos:Document xmlns:pos=(...) xmlns:str=(...) xmlns:xsi=(...) xsi:schemaLocation=(...)>
<pos:DescribeDocument>
(...)
</pos:DescribeDocument>
<pos:UPP>
(...)
</pos:UPP>
<ds:Signature Id="ID-9326" xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo Id="ID-9325" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:pos="adress" xmlns:str="adress" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
(...)
</ds:SignedInfo>
<ds:Object>
<xades:QualifyingProperties Id="ID-9337a6d1" Target="#ID-932668c0-d4f9-11e3-bb2d-001a645ad128" xmlns:xades="http://uri.etsi.org/01903/v1.3.2#">
<xades:SignedProperties Id="ID-9337a6d0" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:pos="adress" xmlns:str="adress" xmlns:xades="adress" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<xades:SignedSignatureProperties>
<xades:SigningTime>sometime</xades:SigningTime>
<xades:SigningCertificate>
<xades:Cert>
<xades:CertDigest>
<ds:DigestMethod Algorithm="adress"/>
<ds:DigestValue>someValue</ds:DigestValue>
</xades:CertDigest>
<xades:IssuerSerial>
<ds:X509IssuerName>CNsomeValue</ds:X509IssuerName>
<ds:X509SerialNumber>SerialsomeValue</ds:X509SerialNumber>
</xades:IssuerSerial>
</xades:Cert>
</xades:SigningCertificate>
<xades:SignaturePolicyIdentifier>
<xades:SignaturePolicyImplied/>
</xades:SignaturePolicyIdentifier>
</xades:SignedSignatureProperties>
<xades:SignedDataObjectProperties>
<xades:DataObjectFormat ObjectReference="#ID-93257e60">
<xades:Description>NEEDVALUE</xades:Description>
</xades:DataObjectFormat>
</xades:SignedDataObjectProperties>
</xades:SignedProperties>
</xades:QualifyingProperties>
</ds:Object>
</ds:Signature>
</pos:Document>
它有一些命名空间。而且我必须获得价值。 我写了一些代码,但没有任何作用:
$xmlFileContent = file_get_contents($pathToXML);
$dom = new SimpleXMLElement($xmlFileContent, LIBXML_COMPACT);
$namespaces = $dom->getNamespaces(true);
foreach ($namespaces as $key => $namespace) {
$dom->registerXPathNamespace($key, $namespace);
}
$matches = $dom->xpath('//xades:Description'); //no success
和
$doms = new DOMDocument;
$doms->loadXML($path);
foreach($doms->getElementsByTagNameNS($namespaces['xades'],'*') as $element){
echo 'local name: ', $element->localName, ', prefix: ', $element->prefix, "\n"; //no success
}
你能帮助我到达这些节点(xades:Description)吗?
PS: 我也用它(但没有成功):
$result1 = $dom->xpath('/Dokument/ds:Signature/ds:Object/xades:QualifyingProperties/xades:SignedProperties/xades:SignedDataObjectProperties/xades:DataObjectFormat/xades:Description');
答案 0 :(得分:2)
您从XML中删除了命名空间定义。如果你看到像&x; xmlns:xades&#39;这样的属性。实际的命名空间是该属性的值。它在当前上下文中为该命名空间定义了别名/前缀。大多数时候URL用作命名空间标识符(因为它避免了潜在的冲突)。但是像urn:somestring
这样的值是有效的。
您还需要在DOMXpath对象上为命名空间注册前缀。此前缀不需要与文档中的前缀相同。以这种方式看待它:
DOMDocument将节点名称从prefix:Description
解析为{namespace-uri}:Description
。
DOMXpath使用自己的定义以相同的方式解析Xpath表达式中的节点名称。例如//prefix:Description
到//{namespace-uri}:Description
。然后它比较已解析的名称。
$dom = new DOMDocument();
$dom->loadXml($xml);
$xpath = new DOMXpath($dom);
$xpath->registerNamespace('x', 'urn:xades');
var_dump($xpath->evaluate('string(//x:Description)'));
string(9) "NEEDVALUE"
答案 1 :(得分:0)
通过修改XPath以忽略命名空间,可能有解决方法,以防您无法找到正确的解决方案:
$result = $dom->xpath('//*[local-name() = "Description"]');