1

编辑:

这是我能想到的最小的 lxml 测试用例(完全用 Python 编写)

from lxml import etree

xslt_tree = etree.XML('''\
<?xml version="1.0" encoding="UTF-8"?>
<MD_Metadata xmlns="http://www.isotc211.org/2005/gmd" xmlns:gco="http://www.isotc211.org/2005/gco">
  <language/>
  <characterSet/>
  </MD_Metadata>''')

doc = etree.XML('''\
  <xsl:stylesheet version="1.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:gmd="http://www.isotc211.org/2005/gmd" >

<!-- This adds the contact tag if it doesn't exist -->
  <xsl:template match="/gmd:MD_Metadata">
     <xsl:copy-of select="*"/>
     <xsl:message>
     Worked
     </xsl:message>
  </xsl:template>
  </xsl:stylesheet>''')

transform = etree.XSLT(doc)

result = transform(xslt_tree)
print transform.error_log
print (etree.tostring(result,pretty_print=True))

这输出

<language xmlns="http://www.isotc211.org/2005/gmd" xmlns:gco="http://www.isotc211.org/2005/gco"/>

什么时候肯定应该输出

<MD_Metadata xmlns="http://www.isotc211.org/2005/gmd" xmlns:gco="http://www.isotc211.org/2005/gco">
  <language/>
  <characterSet/>
  </MD_Metadata>

任何想法为什么?


老问题

我有一个这样的xml文件:

    <?xml version="1.0" encoding="UTF-8"?>
<MD_Metadata xmlns="http://www.isotc211.org/2005/gmd">
  <language>
  <LanguageCode codeList="http://www.loc.gov/standards/iso639-2/php/code_list.php" codeListValue="eng" codeSpace="ISO639-2">eng</LanguageCode>
  </language>
  <characterSet>
   <MD_CharacterSetCode codeList="http://www.isotc211.org/2005/resources/Codelist/gmxCodelists.xml#MD_CharacterSetCode" codeListValue="utf8" codeSpace="ISOTC211/19115">utf8</MD_CharacterSetCode>
  </characterSet>
 .... etc
 </MD_Metadata>

和一个 xlt 文件如下:

 <xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<!-- Show all elements -->
<xsl:template match="@*|node()">
  <xsl:copy>
    <xsl:apply-templates select="@*|node()"/>
  </xsl:copy>
</xsl:template>

<!-- This adds the contact tag if it doesn't exist -->
  <xsl:template match="/gmd:MD_Metadata">
     <xsl:copy-of select="@*|node()">
          <xsl:if test="not(/gmd:MD_Metadata/gmd:contact)">
      <xsl:element name="contact" namespace="http://www.isotc211.org/2005/gmd">
            </xsl:element>
          </xsl:if>
     </xsl:copy-of>
  </xsl:template>

  </xsl:stylesheet>

当我在 Python 中的 lxml 中运行它时,我得到了 MD_Metadata 元素和返回的第一个子元素。但是,当我使用默认的 Java 处理器或 Xalan 在 Eclipse WTP(Eclipse XSL 工具)中运行它时,我得到了从 MD_Metadata 标记返回的所有元素,包括字符集和之后的元素。对我来说,后者是由于标签的预期行为。我在 Python 中调用转换时看不到我在做什么,但以防万一:

xslt_root = lxml.etree.parse("XSLFile")
transform = lxml.etree.XSLT(xslt_root)
result_tree = transform(doc)
print (etree.tostring(result_tree,pretty_print=True))

我正在使用的两个处理器之间是否存在实质性差异,或者是否有其他解释?

4

2 回答 2

1

你得到奇怪行为的原因是它xsl:copy-of应该是一个空元素。我只能假设某些引擎“有用”地试图以xsl:if某种未定义的方式解释导致问题的原因。

删除导致未定义行为的元素,它应该再次在不同的引擎中保持一致。

于 2013-11-11T22:04:32.973 回答
0

啊,它是 XPath。

我想我应该使用<xsl:copy-of select="self::*"/>. 我认为*选择了所有当前节点及其子节点。

感谢帮助

于 2013-11-15T12:44:32.477 回答