>编辑:
这是我能想到的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 Tools)中运行它时,我会得到从 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))
我使用的两个处理器之间是否存在实质性差异,或者是否有其他解释?
你得到奇怪行为的原因是xsl:copy-of
应该是一个空元素。我只能假设一些引擎"有帮助地"试图以某种未定义的方式解释导致麻烦的xsl:if
。
删除导致未定义行为的元素,它应该再次在不同的引擎中保持一致。
啊,是XPath。
我想我应该使用<xsl:copy-of select="self::*"/>
.我认为*
选择了所有当前节点及其子节点。
感谢您的帮助