XSLT无法将元素与特定名称空间匹配 [英] XSLT Can't match element with specific namespace
问题描述
我有这个XML源文件:
I have this XML source file:
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="c:\ISO19139_rve.xsl"?>
<MD_Metadata xmlns="http://www.isotc211.org/schemas/2005/gmd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:gco="http://www.isotc211.org/schemas/2005/gco" xmlns:gml="http://www.opengis.net/gml" xmlns:xlink="http://www.w3.org/1999/xlink" xsi:schemaLocation="http://www.isotc211.org/schemas/2005/gmd/gmd.xsd">
<identificationInfo>
<MD_DataIdentification>
<extent>
<EX_Extent>
<geographicElement>
<EX_GeographicExtent>
<EX_GeographicBoundingBox>
<westBoundLongitude>
<gco:Decimal>1</gco:Decimal>
</westBoundLongitude>
<eastBoundLongitude>
<gco:Decimal>2</gco:Decimal>
</eastBoundLongitude>
<southBoundLatitude>
<gco:Decimal>3</gco:Decimal>
</southBoundLatitude>
<northBoundLatitude>
<gco:Decimal>4</gco:Decimal>
</northBoundLatitude>
</EX_GeographicBoundingBox>
</EX_GeographicExtent>
</geographicElement>
<temporalElement>
<EX_TemporalExtent>
<extent>
<gml:TimePeriod gml:id="tp1">
<gml:begin>
<gml:TimeIstant gml:id="ti1">
<gml:timePosition>2007-12-01</gml:timePosition>
</gml:TimeIstant>
</gml:begin>
<gml:end>
<gml:TimeIstant gml:id="ti2">
<gml:timePosition>2010-01-01</gml:timePosition>
</gml:TimeIstant>
</gml:end>
</gml:TimePeriod>
</extent>
</EX_TemporalExtent>
</temporalElement>
</EX_Extent>
</extent>
</MD_DataIdentification>
</identificationInfo>
</MD_Metadata>
我需要用这个简单的块替换该块:
And I need to replace the block with this simple one:
...
<gml:TimePeriod gml:id="TP1">
<gml:beginPosition>2007-12-01</gml:beginPosition>
<gml:endPosition>2010-01-01</gml:endPosition>
</gml:TimePeriod>
...
这是我的转变:
<xsl:stylesheet
version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:gml="http://www.opengis.net/gml/3.2"
xmlns:gco="http://www.isotc211.org/schemas/2005/gco"
xmlns:gmd="http://www.isotc211.org/schemas/2005/gmd"
xmlns="http://www.isotc211.org/schemas/2005/gmd"
>
<xsl:strip-space elements="*"/>
<xsl:output indent="yes" encoding="UTF-8"/>
<!-- identity template -->
<xsl:template match="node() | @*">
<xsl:copy>
<xsl:apply-templates select="node() | @*" />
</xsl:copy>
</xsl:template>
<xsl:template match="gml:TimePeriod">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<beginPosition>
<xsl:value-of select="gml:begin/gml:TimeIstant/gml:timePosition"/>
</beginPosition>
<endPosition>
<xsl:value-of select="gml:end/gml:TimeIstant/gml:timePosition"/>
</endPosition>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
在样式表的顶部有xmlns:gml="http://www.opengis.net/gml"
声明,但我认为这是名称空间的问题.
如果我在
There's the xmlns:gml="http://www.opengis.net/gml"
declaration on the top of the stylesheet but I think it's a matter of namespace.
If I put a break point near the
<xsl:template match="gml:TimePeriod" exclude-result-prefixes="#all">
行,我从不输入该代码.
看来,如果我需要遍历<gmd:...>
元素,则一切正常,但是当我需要到达<gml:...>
(或与gmd不同的其他任何元素)时,它不匹配.
line, I never enter inside that code.
It seems that if I need to go through <gmd:...>
elements, all works fine, but when I need to reach a <gml:...>
(or any other different from gmd) element, it doesn't match.
-更新于2014-04-15-
我忘记指定我还需要将<gml:TimePeriod gml:id="tp1">
元素的"tp1"
属性值转换为大写.我需要在实际转换中进行哪些更改?
I forgot to specify that I also need to convert to UPPER-CASE the "tp1"
attribute value of <gml:TimePeriod gml:id="tp1">
element. What do I need to change on my actual transformation?
推荐答案
正如Tomalak在评论中提到的,问题的根本原因是,您有不同的名称空间URI映射到输入XML和输入XML中的gml
前缀.您的样式表,因此XML中的元素与XSLT希望匹配的元素不会被视为相同.
As Tomalak mentions in the comments, the root cause of your problem is that you have different namespace URIs mapped to the gml
prefix in your input XML and in your stylesheet, so the elements in your XML and the elements that the XSLT is looking to match are not considered the same.
关于您的添加:
我忘记指定我还需要将
<gml:TimePeriod gml:id="tp1">
元素的"tp1"属性值转换为大写.我需要在实际转换中进行哪些更改?
I forgot to specify that I also need to convert to UPPER-CASE the "tp1" attribute value of
<gml:TimePeriod gml:id="tp1">
element. What do I need to change on my actual transformation?
这应该是添加一个额外的模板(一旦您已经命名空间对齐)并使用XPath 2.0 upper-case
函数的问题:
this should just be a matter of adding one extra template (once you've got the namespaces aligned) and using the XPath 2.0 upper-case
function:
<xsl:template match="gml:TimePeriod/@gml:id">
<xsl:attribute name="gml:id" select="upper-case(.)" />
</xsl:template>
这将仅影响gml:TimePeriod
元素的ID,如果您要大写 all 这些ID,则只需将其设为match="@gml:id"
.
This will affect only the ids of gml:TimePeriod
elements, if you want to upper-case all the IDs then simply make it match="@gml:id"
instead.
这篇关于XSLT无法将元素与特定名称空间匹配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!