我收到第三方供稿,我无法确定其名称空间,所以我当前不得不在我的XSLT中使用local-name()函数来获取元素值。但是我需要从一个这样的元素中获取一个属性,当命名空间未知时我不知道如何执行此操作(因此需要local-name()函数)。
N.B。我使用.net 2.0来处理XSLT
以下是XML示例:
<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<id>some id</id>
<title>some title</title>
<updated>2008-09-11T15:53:31+01:00</updated>
<link rel="self" href="http://www.somefeedurl.co.uk" />
<author>
<name>some author</name>
<uri>http://someuri.co.uk</uri>
</author>
<generator uri="http://aardvarkmedia.co.uk/">AardvarkMedia script</generator>
<entry>
<id>http://soemaddress.co.uk/branded3/80406</id>
<title type="html">My Ttile</title>
<link rel="alternate" href="http://www.someurl.co.uk" />
<updated>2008-02-13T00:00:00+01:00</updated>
<published>2002-09-11T14:16:20+01:00</published>
<category term="mycategorytext" label="restaurant">Test</category>
<content type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml">
<div class="vcard">
<p class="fn org">some title</p>
<p class="adr">
<abbr class="type" title="POSTAL" />
<span class="street-address">54 Some Street</span>
,
<span class="locality" />
,
<span class="country-name">UK</span>
</p>
<p class="tel">
<span class="value">0123456789</span>
</p>
<div class="geo">
<span class="latitude">51.99999</span>
,
<span class="longitude">-0.123456</span>
</div>
<p class="note">
<span class="type">Review</span>
<span class="value">Some content</span>
</p>
<p class="note">
<span class="type">Overall rating</span>
<span class="value">8</span>
</p>
</div>
</div>
</content>
<category term="cuisine-54" label="Spanish" />
<Point xmlns="http://www.w3.org/2003/01/geo/wgs84_pos#">
<lat>51.123456789</lat>
<long>-0.11111111</long>
</Point>
</entry>
</feed>
这是XSLT
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:wgs="http://www.w3.org/2003/01/geo/wgs84_pos#" exclude-result-prefixes="atom wgs">
<xsl:output method="xml" indent="yes"/>
<xsl:key name="uniqueVenuesKey" match="entry" use="id"/>
<xsl:key name="uniqueCategoriesKey" match="entry" use="category/@term"/>
<xsl:template match="/">
<locations>
<!-- Get all unique venues -->
<xsl:for-each select="/*[local-name()='feed']/*[local-name()='entry']">
<xsl:variable name="CurrentVenueKey" select="*[local-name()='id']" ></xsl:variable>
<xsl:variable name="CurrentVenueName" select="*[local-name()='title']" ></xsl:variable>
<xsl:variable name="CurrentVenueAddress1" select="*[local-name()='content']/*[local-name()='div']/*[local-name()='div']/*[local-name()='p'][@class='adr']/*[local-name()='span'][@class='street-address']" ></xsl:variable>
<xsl:variable name="CurrentVenueCity" select="*[local-name()='content']/*[local-name()='div']/*[local-name()='div']/*[local-name()='p'][@class='adr']/*[local-name()='span'][@class='locality']" ></xsl:variable>
<xsl:variable name="CurrentVenuePostcode" select="*[local-name()='postcode']" ></xsl:variable>
<xsl:variable name="CurrentVenueTelephone" select="*[local-name()='telephone']" ></xsl:variable>
<xsl:variable name="CurrentVenueLat" select="*[local-name()='Point']/*[local-name()='lat']" ></xsl:variable>
<xsl:variable name="CurrentVenueLong" select="*[local-name()='Point']/*[local-name()='long']" ></xsl:variable>
<xsl:variable name="CurrentCategory" select="WHATDOIPUTHERE"></xsl:variable>
<location>
<locationName>
<xsl:value-of select = "$CurrentVenueName" />
</locationName>
<category>
<xsl:value-of select = "$CurrentCategory" />
</category>
<description>
<xsl:value-of select = "$CurrentVenueName" />
</description>
<venueAddress>
<streetName>
<xsl:value-of select = "$CurrentVenueAddress1" />
</streetName>
<town>
<xsl:value-of select = "$CurrentVenueCity" />
</town>
<postcode>
<xsl:value-of select = "$CurrentVenuePostcode" />
</postcode>
<wgs84_latitude>
<xsl:value-of select = "$CurrentVenueLat" />
</wgs84_latitude>
<wgs84_longitude>
<xsl:value-of select = "$CurrentVenueLong" />
</wgs84_longitude>
</venueAddress>
<venuePhone>
<phonenumber>
<xsl:value-of select = "$CurrentVenueTelephone" />
</phonenumber>
</venuePhone>
</location>
</xsl:for-each>
</locations>
</xsl:template>
</xsl:stylesheet>
我正在尝试将$ CurrentCategory变量替换为显示 mycategorytext
的相应代码答案 0 :(得分:12)
我这里没有XSLT编辑器,但您尝试过使用
*[local-name()='category']/@*[local-name()='term']
答案 1 :(得分:2)
根据http://www.w3.org/TR/2006/REC-xml-names-20060816/#scoping-defaulting
“默认命名空间声明不直接应用于属性名称;未加前缀属性的解释由它们出现的元素决定。”
这意味着您的属性不在命名空间中。只需使用“@term”即可。
为了更清楚一点,不需要使用local-name()来解决这个问题。 处理它的传统方法是在XSLT中声明atom命名空间的前缀,然后在xpath查询中使用它。
你已经在你的样式表元素上得到了这个声明(xmlns:atom =“http://www.w3.org/2005/Atom”),所以剩下的就是使用它。
正如我已经解释的那样,该属性不受默认命名空间的影响,因此您的代码看起来像这样(假设您要添加“xmlns:xhtml ='http://www.w3.org/1999/xhtml'”):
<xsl:for-each select="/atom:feed/atom:entry">
<xsl:variable name="CurrentVenueKey" select="atom:id" />
<xsl:variable name="CurrentVenueName" select="atom:title" />
<xsl:variable name="CurrentVenueAddress1"
select="atom:content/xhtml:div/xhtml:div/xhtml:p[@class='adr']/xhtml:span[@class='street-address']" />
<xsl:variable name="CurrentVenueCity"
select="atom:content/xhtml:div/xhtml:div'/xhtml:p[@class='adr']/xhtml:span[@class='locality'] />
...
<xsl:variable name="CurrentCategory" select="atom:category/@term" />
.....
如果你真的不知道你正在转换的XML的结构,那么local-name()会非常有用,但是在这种情况下,如果你收到的东西不是你所期望的,那么它会破坏任何案件。
答案 2 :(得分:0)
我不确定为什么你必须使用local-name(),但是如果你分享一些关于你使用的xslt处理器以及语言的更多信息,那么我可以理解。我说这个b / c你应该可以这样做:
<xsl:stylesheet xmlns="http://www.w3.org/2005/Atom" ..>
<xsl:template match="feed">
<xsl:apply-templates />
</xsl:template>
<xsl:template match="entry">
...
<xsl:variable name="current-category" select="category/@term" />
...
</xsl:template>
我希望帮助你的两件事是顶部没有前缀的xmlns声明。这将设置默认命名空间,因此您不必使用命名空间前缀。同样,您可以调用do'xmlns:a =“http://www.w3.org/2005/Atom”'然后执行'select =“a:feed”'。另一件需要注意的事情是使用选择属性的'@term'。如果你想匹配任何属性'@ *'就像它对元素一样。
同样,根据处理器的不同,可能还有其他有用的工具供您使用,因此如果您可以提供更多信息,则可能有所帮助。此外,XSL mailing list可能是另一个有用的资源。