使用XSLT删除模式和命名空间的问题

时间:2017-04-07 17:50:16

标签: xml xslt xsd xml-parsing xslt-1.0

我目前正在尝试解析加拿大每日气候数据的环境,从以属性为中心到以元素为中心的风格,这样我就可以将结果导入到访问数据库中。

我按照我想要的方式让它工作,但它需要我手动切出

<climatedata **xmlns:xsd="dummylink" xsd:schemaLocation="dummylink.xsd"**>

为了让它发挥作用。

我已经在我的XSLT中添加了代码以从文档中的根元素中删除命名空间,但是当我这样做时,它最终只改变了我的标记变换的方式。这意味着我的工作站数据标签不再将其属性格式化为元素。

这是XML(在我的XSLT之后),缩短为仅查看元素数据的第一天。正如您所看到的,它从schemalocation中删除了 xmlns:xsd =&#34; dummylink&#34; xsd 前缀,但保留了 schemalocation 和现在错误地格式化 stationdata

<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet type="text/xsl" href="EnvCanStack.xsl"?>

<climatedata schemaLocation="http://www.climate.weatheroffice.gc.ca/climateData/bulkxml/bulkschema.xsd">

<lang>ENG</lang>

<stationinformation>

<name>OSHAWA WPCP</name>
<province>ONTARIO</province>
<latitude>43.87</latitude>
<longitude>-78.83</longitude>
<elevation>83.80</elevation>
<climate_identifier>6155878</climate_identifier>
<wmo_identifier></wmo_identifier>
<tc_identifier></tc_identifier>

</stationinformation>

<stationdata day="1" month="1" year="2017">

<maxtemp>4.0</maxtemp>
<mintemp>0.0</mintemp>
<meantemp>2.0</meantemp>16.00.0<totalrain>0.0</totalrain>
<totalsnow>0.0</totalsnow>
<totalprecipitation>0.0</totalprecipitation>
<snowonground>5</snowonground>

</stationdata>

</climatedata>

这是我的XSLT

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
  <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
  <xsl:strip-space elements="*"/>

  <!-- BY DEFAULT, elements and text nodes are copied,
       and elements' attributes and contents are transformed as child nodes
       of the output element -->
  <xsl:template match="node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>

  <!-- By default, attributes are transformed to elements -->
  <xsl:template match="@*">
    <xsl:element name="{name()}">
      <xsl:value-of select="."/>
    </xsl:element>
  </xsl:template>

  <!-- Certain elements have only their contents transformed -->
  <xsl:template match="dirofmaxgust | speedofmaxgust | heatdegdays | cooldegdays">
    <!-- no xsl:copy, and attribute children, if any, are ignored -->
    <xsl:apply-templates select="@* | node()"/>
  </xsl:template>

  <!-- Removes specific attributes (@) to be removed. Blank template body means
        the "transformation" will ignore them or basically re print them blank -->
<xsl:template match="@description|@units|@quality"/>

<!-- Where I'm trying to remove the namespace/schemalocation -->
  <xsl:template match="*">
    <xsl:element name="{local-name(.)}">
      <xsl:apply-templates select="@* | node()"/>
    </xsl:element>
  </xsl:template>

  <xsl:template match="@*">
    <xsl:attribute name="{local-name(.)}">
      <xsl:value-of select="."/>
    </xsl:attribute>
  </xsl:template>

</xsl:stylesheet>

仅供参考,当我手动剪切命名空间并且不包含为我执行此操作的代码时,这就是我的XML的样子。

<?xml-stylesheet type="text/xsl" href="EnvCanStack.xsl"?>

<climatedata>

<lang>ENG</lang>

<stationinformation>

<name>OSHAWA WPCP</name>
<province>ONTARIO</province>
<latitude>43.87</latitude>
<longitude>-78.83</longitude>
<elevation>83.80</elevation>
<climate_identifier>6155878</climate_identifier>
<wmo_identifier>
</wmo_identifier>
<tc_identifier>
</tc_identifier>

</stationinformation>

<stationdata>

<day>1</day>
<month>1</month>
<year>2017</year>
<maxtemp>4.0</maxtemp>
<mintemp>0.0</mintemp>
<meantemp>2.0</meantemp>
<totalrain>0.0</totalrain>
<totalsnow>0.0</totalsnow>
<totalprecipitation>0.0</totalprecipitation>
<snowonground>5</snowonground>

</stationdata>

</climatedata>

在你讨厌我如何设置它之前,我是学生程序员,我非常擅长XML / XSLT所以任何建议/见解/解释为什么会发生这种情况我将能够解决它将非常感激。

1 个答案:

答案 0 :(得分:0)

您有不同优先级的冲突模板规则。请查看XSLT优先级如何工作的概述http://lenzconsulting.com/how-xslt-works/#priority

删除以下适用的模板规则

<!-- By default, attributes are transformed to elements -->
<xsl:template match="@*">
  <xsl:element name="{name()}">
    <xsl:value-of select="."/>
  </xsl:element>
  </xsl:template>
</xsl:template>

并在末尾替换属性模板,如下所示

  <xsl:template match="@*">
<xsl:choose>
    <xsl:when test="local-name(.)='schemaLocation'">
      <xsl:attribute name="{local-name(.)}">
        <xsl:value-of select="."/>
      </xsl:attribute>
    </xsl:when>
    <xsl:otherwise>
        <xsl:element name="{name()}">
         <xsl:value-of select="."/>
        </xsl:element>
    </xsl:otherwise>
  </xsl:choose>