开发者

Problem transforming XML with XSLT

开发者 https://www.devze.com 2023-03-09 07:06 出处:网络
I am having problem transforming xml to xml using xsl. I found out where the problem comes from but still don\'t know how to fix it.

I am having problem transforming xml to xml using xsl. I found out where the problem comes from but still don't know how to fix it.

<?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>   

I think the problems comes from this line

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

If I remove the "uri="" xmlns="http://dl.kr.org/dig/2003/02/lang"" and leave only the

"<tells>" 

everything works perfectly. But is there a way to transform it without removing it?

<?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 n开发者_如何学Pythoname="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>


You are correct: the reason your transformation isn't working is that you have a namespace declaration on the tells element.

To make this particular problem go away, you need to make your XSLT aware of the namespace, and tell it that the tells element that it's trying to transform belongs to that namespace. The most common way to do this is to declare a namespace prefix in the xsl:stylesheet element, and then use that prefix in the XPath, e.g.:

<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>

The xmlns:n attribute at the top of the stylesheet tells the XSLT processor that the 'http://dl.kr.org/dig/2003/02/lang' namespace exists, and that the n: prefix is an abbreviation for it. In the select and match attributes, the n: prefix tells the XSLT processor that when it's looking for elements named tells, it should look for elements with that name that are in the http://dl.kr.org/dig/2003/02/lang namespace.

XML namespaces are an essential part of XML technologies, and people often overlook them when they're learning XML - they're complicated and not very intuitive, and you can ignore them for quite a while when you're coming up to speed on XML. But there comes a point where you can no longer afford the simplifying assumption that namespaces don't exist, and you're at that point.


When dealing with namespaces you have to declare them in your transform; otherwise you won't be able to select the document nodes correctly.


Well without seeing your XSLT code we can't fix it. Nevertheless, the xmlns="http://dl.kr.org/dig/2003/02/lang" means the tells elements and its descendant elements are in that namespace so your XSLT needs to take that into account. With XSLT 1.0 your stylesheet needs to bind a prefix to the namespace URI and use that prefix in XPath expressions and XSLT match patterns to qualify element names e.g.

<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>
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号