XSLT Невозможно сопоставить элемент с определенным пространством имен
У меня есть этот исходный файл XML:
<?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>
И мне нужно заменить блок на этот простой:
...
<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"
объявление в верхней части таблицы стилей, но я думаю, что это вопрос пространства имен. Если я поставлю точку останова рядом с
<xsl:template match="gml:TimePeriod" exclude-result-prefixes="#all">
строка, я никогда не введу внутри этого кода. Кажется, что если мне нужно пройти <gmd:...>
элементы, все работает нормально, но когда мне нужно достичь <gml:...>
(или любой другой элемент, отличный от gmd), он не совпадает.
- ОБНОВЛЕНО 2014-04-15 -
Я забыл указать, что мне также нужно преобразовать в верхний регистр "tp1"
значение атрибута <gml:TimePeriod gml:id="tp1">
элемент. Что мне нужно изменить в моей реальной трансформации?
1 ответ
Как упоминает Томалак в комментариях, основная причина вашей проблемы заключается в том, что у вас есть разные URI пространства имен, сопоставленные с gml
префикс во входном XML и в вашей таблице стилей, поэтому элементы в вашем XML и элементы, которым XSLT стремится соответствовать, не считаются одинаковыми.
Что касается вашего дополнения:
Я забыл указать, что мне также нужно преобразовать в UPPER-CASE значение атрибута "tp1"
<gml:TimePeriod gml:id="tp1">
элемент. Что мне нужно изменить в моей реальной трансформации?
это просто вопрос добавления одного дополнительного шаблона (после выравнивания пространств имен) и использования XPath 2.0 upper-case
функция:
<xsl:template match="gml:TimePeriod/@gml:id">
<xsl:attribute name="gml:id" select="upper-case(.)" />
</xsl:template>
Это повлияет только на идентификаторы gml:TimePeriod
элементы, если вы хотите в верхнем регистре все идентификаторы, то просто сделайте это match="@gml:id"
вместо.