local-name如何在xml节点中查找属性?

时间:2014-08-22 20:22:31

标签: xml xslt

我正在尝试在这样的XML节点中选择一个属性:

<tdf:TrustedDataObject xmlns="urn:com:bank:baml:tdf" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:gml="http://www.opengis.net/gml" >

我能够使用Firepath找到节点,如下所示:

/*[local-name()='TrustedDataObject']

但是如果我想选择节点内的属性,比如gml属性,我不知道该怎么做。我尝试了几种不同的方式:

/*[local-name()='TrustedDataObject']/@gml

/*[local-name()='TrustedDataObject'][gml]

它们与任何东西都不匹配。

有人有什么建议吗?我知道这不是完整的代码,我现在无法访问整个文档,所以我道歉。

编辑 - 好的,我不确定是否应该开始另一个问题或者只是编辑我的原文。我理解在尝试访问命名空间属性时存在一些限制,但我真正想要做的是在NoticeText中的属性上创建一个内容节点,如 - ownerProducer和pocType。

<document>
   <tdf:TrustedDataObject xmlns="urn:com:bank:baml:tdf" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:gml="http://www.opengis.net/gml" >
      <ism:Notice ism:classification="X" ism:ownerProducer="ABC" ism:noticeType="POC" ism:externalNotice="true">
        <ism:NoticeText ism:classification="X" ism:ownerProducer="ABC" ism:pocType="JJJ-710">John Smith, Walmart, jsmith@walmart.com</ism:NoticeText>
      </ism:Notice>
   </tdf:TrustedDataObject>
<document>

同样,我认为能够遍历到NoticeText节点,使用local-name()应该可以工作。像这样的东西?

//*[local-name()='NoticeText']/@ownerProducer  

再次感谢您的帮助。也许你告诉我所有这些属性都无法通过xpath ...

访问

3 个答案:

答案 0 :(得分:6)

通常,xpath处理器允许您注册名称空间,因此xpath将(已使用相同的前缀注册名称空间)

//ism:NoticeText/@ism:ownerProducer

例如,在XSLT中,您将使用命名空间声明在模板的XML中注册命名空间,然后在xpath表达式中使用前缀

<xsl:stylesheet version="2.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns="http://www.w3.org/1999/xhtml"
                xmlns:ism="urn:us:gov:ic:ism">
<xsl:template match="/">
<result>
<xsl:value-of select="//ism:NoticeText/@ism:ownerProducer">
</result>
</xsl:template>
</xsl:stylesheet>

根据this answer,您在使用FirePath时无法注册名称空间,因此解决方法是仅查看本地名称。请注意,如果其他名称空间使用相同的本地名称,这可能会导致问题 - 当您执行此操作时,您将击败名称空间的整个点,因此请在生产代码中使用更好的工具。

因此,要从本地名称为“NoticeText”的所有元素中选择本地名称为“ownerProducer”的所有属性,而不考虑名称空间,xpath将为

//*[local-name()='NoticeText']/@*[local-name()='ownerProducer'] 

分解
//                             a descendent of the current context
*                              any element
[local-name()='NoticeText']    whose local name is 'NoticeText'
/                              a child of the current context
@*                             any attribute
[local-name()='ownerProducer'] whole local name is 'ownerProducer'

答案 1 :(得分:1)

虽然XML元素有三个属性,但它们都是名称空间声明,而在XSLT和XPath数据模型中,名称空间声明不会在树中显示为属性。因此,使用XPath,您无法访问这些属性,您所能做的就是访问命名空间轴范围内的命名空间节点。

有关命名空间节点的详细信息,请参阅http://www.w3.org/TR/xpath/#namespace-nodes

答案 2 :(得分:0)

由于gml不是如上所述的属性。如果您仍想在我们的输出中访问gml命名空间的值。请使用以下代码

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="1.0">
<xsl:template match="/">        
     <output> <xsl:value-of select="/*/namespace::node()[local-name()='gml']"></xsl:value-of></output>
</xsl:template>
</xsl:stylesheet>

输入:

<tdf:TrustedDataObject xmlns:tdf="urn:com:bank:baml:tdf" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:gml="http://www.opengis.net/gml" >
 </tdf:TrustedDataObject>    

输出:

   <output>http://www.opengis.net/gml</output>