如何处理XML命名空间
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何处理XML命名空间相关的知识,希望对你有一定的参考价值。
我有一种感觉,这个问题很简单,但是自从我做了任何xslt以来可能有多年,所以也许有人可以提供帮助?
我有一块由.net类DataContractSerializer生成的xml,我需要使用xslt从这个xml中提取数据,最后得到一些html。对我来说复杂的事情是命名空间的大量使用......
xml的片段如下所示:
<FundDeal xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/Guide.Rx.BusinessObjects.Deal">
<Id xmlns="http://schemas.datacontract.org/2004/07/Guide.BusinessObjects.Deal">DEAL12345</Id>
<Account xmlns:d2p1="http://schemas.datacontract.org/2004/07/Guide.Rx.BusinessObjects.Account">
<d2p1:AlternateId i:nil="true"/>
<d2p1:Designation>XXX</d2p1:Designation>
<d2p1:Name>QWERTY</d2p1:Name>
<d2p1:Number>12345678</d2p1:Number>
<d2p1:Status i:nil="true"/>
</Account>
<Agent xmlns:d2p1="http://schemas.datacontract.org/2004/07/Guide.Rx.BusinessObjects.Account">
<d2p1:Id>54321</d2p1:Id>
<d2p1:Name>ASDFG</d2p1:Name>
<d2p1:Status>Active</d2p1:Status>
</Agent>
....
</FundDeal>
现在,我需要通过样式表来转换这个xml,并且发现它非常艰难。我认识到xsl需要它自己对所涉及的命名空间的引用,并且可以使用以下xsl轻松地提取上面的Deal Id之类的内容:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ms="urn:schemas-microsoft-com:xslt"
xmlns:grbd="http://schemas.datacontract.org/2004/07/Guide.Rx.BusinessObjects.Deal"
xmlns:gbd="http://schemas.datacontract.org/2004/07/Guide.BusinessObjects.Deal"
xmlns:grba="http://schemas.datacontract.org/2004/07/Guide.Rx.BusinessObjects.Account">
<xsl:output indent="yes" omit-xml-declaration="yes" method="html"/>
<xsl:template match="/">
<html>
<head>
<!-- some styles here -->
</head>
<body>
<table cellpadding="5" cellspacing="5" border="0">
<tr>
<td class="SectionTitle" colspan="2">
<xsl:text>Deal Cancellation Notification - </xsl:text>
<xsl:value-of select="//ggbd:Id"/>
</td>
</tr>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
但我正在努力阅读诸如帐户名之类的内容,因为似乎有多个名称空间正在进行中。
任何人都可以告诉我访问的xpath(a)帐户名称,以及(b)代理商名称?我认为看到如何访问这些将可能允许我访问我需要的一切。
非常感谢,皮特
这会起作用,但这不是正确的方法:
//*[local-name()='Account']/grba:Name
和
//*[local-name()='Agent']/grba:Name
更好地看待您的输入,您有父命名空间。您需要选择元素的正确名称空间。例如Account
和Agent
在grbd
范围内,而Name
在grba
。在命名空间声明后,您可以选择如下:
//grbd:Account/grba:Name
要么
//grbd:Agent/grba:Name
具有前缀命名空间的元素也是如此。否则你应该选择本地的。例如,对于第一个Id
节点,您需要:
//gbd:Id
如果您打算使用XML,那么值得深入了解命名空间 - 这可能是痛苦的。从长远来看,推迟你的理解只会让事情变得更加痛苦。
帐户名称或代理名称没有“多个名称空间”:元素最多只能存在一个名称空间。
您看到的大多数命名空间语法仅仅是命名空间名称(URI)的绑定名称空间前缀。所以当你看到
xmlns:i="http://www.w3.org/2001/XMLSchema-instance"
这将前缀“i”绑定到URI“http://www.w3.org/2001/XMLSchema-instance”,因此文档中的更深层元素可能使用“i”前缀(基本上作为一种保存方式)按键)。
当xmlns属性自己指定一个值时(即你看到xmlns =“something”),这意味着Namespace是该元素及其后代的效果(除非被更深层次指定的另一个命名空间覆盖) 。
因此,在您的示例文档(有点像Namespace hodge-podge)中,根FundDeal元素的命名空间名称是“http://schemas.datacontract.org/2004/07/Guide.Rx.BusinessObjects.Deal” ,这也是其子Account和Agent元素的情况(虽然它们碰巧定义了一个名称空间/前缀绑定,但它不影响它们自己的Namespace:这个绑定由它们的子元素使用)。
您可以通过绑定自己的前缀(下面的示例中的“fund”和“deal”)来最容易地在样式表中指定命名空间,以引用您需要的命名空间(我添加了一些我希望它更清晰一些) :
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fund="http://schemas.datacontract.org/2004/07/Guide.Rx.BusinessObjects.Deal"
xmlns:deal="http://schemas.datacontract.org/2004/07/Guide.BusinessObjects.Deal"
xmlns:d2p1="http://schemas.datacontract.org/2004/07/Guide.Rx.BusinessObjects.Account">
<xsl:output indent="yes" omit-xml-declaration="yes" method="html"/>
<xsl:template match="/">
<html>
<head>
<!-- some styles here -->
</head>
<body>
<table cellpadding="5" cellspacing="5" border="0">
<tr>
<td class="SectionTitle" colspan="2">
<xsl:text>Deal Cancellation Notification - </xsl:text>
<xsl:value-of select="/fund:FundDeal/deal:Id"/>
<br/>
<xsl:text>Account Name - </xsl:text>
<xsl:value-of select="/fund:FundDeal/fund:Account/d2p1:Name"/>
<br/>
<xsl:text>Agent Name - </xsl:text>
<xsl:value-of select="/fund:FundDeal/fund:Agent/d2p1:Name"/>
</td>
</tr>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
你可以看到:http://www.xml.com/pub/a/2001/05/02/trxml.html
以上是关于如何处理XML命名空间的主要内容,如果未能解决你的问题,请参考以下文章