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" вместо.

Другие вопросы по тегам