【问题标题】:Problem transforming XML with XSLT使用 XSLT 转换 XML 的问题
【发布时间】:2011-05-31 17:15:40
【问题描述】:

我在使用 xsl 将 xml 转换为 xml 时遇到问题。我发现问题出在哪里,但仍然不知道如何解决它。

<?xml version="1.0" encoding="UTF-8"?>
<tells uri="" xmlns="http://dl.kr.org/dig/2003/02/lang">
  <impliesc>
    <catom name="name1"/>
    <catom name="name2"/>
  </impliesc>
  <impliesc>
    <catom name="name3"/>
    <catom name="name4"/>
  </impliesc>
</tells>   

我认为问题出在这一行

<tells uri="" xmlns="http://dl.kr.org/dig/2003/02/lang">

如果我删除 "uri="" xmlns="http://dl.kr.org/dig/2003/02/lang"" 并只留下

"<tells>" 

一切都很完美。但是有没有办法在不移除的情况下对其进行改造?

<?xml version="1.0" encoding="utf-8"?>

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>

<xsl:template match="/">

    <xsl:element name="tells">

        <xsl:for-each select="./tells/impliesc">

            <xsl:element name="impliesc">

                <xsl:for-each select="./tells/impliesc/catom">

                    <xsl:element name="catom">

                        <xsl:attribute name="name">
                            <xsl:value-of select="./tells/impliesc/individual/@name"/>
                        </xsl:attribute>

                     </xsl:element>

                </xsl:for-each>

            </xsl:element>

        </xsl:for-each>

    </xsl:element>

</xsl:template>

</xsl:stylesheet>

【问题讨论】:

  • 你能展示一下你的变换吗?
  • 您可以发布您的 XSLT 工作表来帮助我们找到问题。

标签: xml xslt


【解决方案1】:

您是对的:您的转换不起作用的原因是您在 tells 元素上有一个命名空间声明。

要消除这个特殊问题,您需要让 XSLT 知道命名空间,并告诉它它尝试转换的 tells 元素属于该命名空间。最常见的方法是在 xsl:stylesheet 元素中声明命名空间前缀,然后在 XPath 中使用该前缀,例如:

<xsl:stylesheet xmlns:n="http://dl.kr.org/dig/2003/02/lang" ... >
   ...
   <xsl:template match="/">
      <output>
         <xsl:apply-templates select="//n:tells"/>
      </output>
   </xsl:template>

   <xsl:template match="n:tells">
      ...
   </xsl:template>

<xsl:stylesheet>

样式表顶部的xmlns:n 属性告诉XSLT 处理器“http://dl.kr.org/dig/2003/02/lang”命名空间存在,并且n: 前缀是它的缩写。在selectmatch 属性中,n: 前缀告诉XSLT 处理器,当它在寻找名为tells 的元素时,它应该在http://dl.kr.org/dig/2003/02/lang 命名空间中寻找具有该名称的元素。

XML 命名空间是 XML 技术的重要组成部分,人们在学习 XML 时经常会忽略它们——它们很复杂而且不是很直观,当你开始学习时你可以忽略它们很长一段时间XML 上的速度。但是有一点你不能再承受命名空间不存在的简化假设,而你就在那个时候。

【讨论】:

  • &lt;xsl:template match="n:tells"&gt; 中,不要忘记XPath 中的每个节点都必须带有n: 前缀。例如:n:impliesc/n:catom[@name='name1'].
【解决方案2】:

在处理命名空间时,您必须在转换中声明它们;否则将无法正确选择文档节点。

【讨论】:

    【解决方案3】:

    如果没有看到您的 XSLT 代码,我们将无法修复它。不过,xmlns="http://dl.kr.org/dig/2003/02/lang" 表示 tells 元素及其后代元素位于该名称空间中,因此您的 XSLT 需要考虑到这一点。使用 XSLT 1.0,您的样式表需要将前缀绑定到命名空间 URI,并在 XPath 表达式和 XSLT 匹配模式中使用该前缀来限定元素名称,例如

    <xsl:stylesheet
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns:df="http://dl.kr.org/dig/2003/02/lang"
      exclude-result-prefixes="df"
      version="1.0">
    
      <-- examples -->
      <xsl:template match="df:tells">
        <foo>
         <xsl:apply-templates/>
        </foo>
      </xsl:template>
    
      <xsl:template match="df:impliesc">
        <bar>
          <xsl:apply-templates select="df:catom[1]"/>
        </bar>
      </xsl:template>
    
    </xsl:stylesheet>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-05
      • 1970-01-01
      • 2011-08-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多