使用XSLT转换XML会产生错误的结果

时间:2019-01-28 21:30:20

标签: python xml xslt lxml

我想将一项XML转换为两行HTML

from lxml import etree


xroot = etree.XML(b'''<?xml version="1.0" encoding="utf-8"?>
    <xml>
        <name>donald</name>
        <surname>trump</surname>
    </xml>
    ''')
xml=etree.ElementTree(xroot)
xslt_root = etree.XML('''
     <xsl:stylesheet version="1.0"
         xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
         <xsl:template match="xml">
             <div id='name'><xsl:value-of select="name" /></div>
             <div id='surname'><xsl:value-of select="surname" /></div>
         </xsl:template>
 </xsl:stylesheet>''')
transform = etree.XSLT(xslt_root)
transform=etree.XSLT(xslt_root)
html=etree.tostring(transform(xml)).decode('utf-8')
print(html)

我期望的结果是:

 <div id='name'>donald</div>
 <div id='surname'>trump</div>

但是我得到的结果是:

 <div id='name'>donald</div>

为什么?

2 个答案:

答案 0 :(得分:2)

可能是因为转换的结果不是well-formed XML(因为您没有单个根元素;您有两个div元素)。

将格式不正确的XML传递给tostring(),它期望元素(单数)或树,这似乎是您仅看到第一个结果元素的原因。

如果将div包裹在单个元素中(例如test),则会看到两个div ......

from lxml import etree

xroot = etree.XML(b'''<?xml version="1.0" encoding="utf-8"?>
    <xml>
        <name>donald</name>
        <surname>trump</surname>
    </xml>
    ''')
xml = etree.ElementTree(xroot)
xslt_root = etree.XML('''
     <xsl:stylesheet version="1.0"
         xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
         <xsl:template match="xml">
             <test>
                 <div id='name'><xsl:value-of select="name" /></div>
                 <div id='surname'><xsl:value-of select="surname" /></div>
             </test>
         </xsl:template>
 </xsl:stylesheet>''')
transform = etree.XSLT(xslt_root)
html = etree.tostring(transform(xml)).decode('utf-8')
print(html)

打印输出...

<test><div id="name">donald</div><div id="surname">trump</div></test>

仅打印转换结果(print(transform(xml)))也会显示两个div(对XSLT不变)。

答案 1 :(得分:-1)

我不确定原因,但是这样做

from lxml import etree

xroot = etree.XML(b'''<?xml version="1.0" encoding="utf-8"?>
    <xml>
        <name>donald</name>
        <surname>trump</surname>
    </xml>
    ''')
xml = etree.ElementTree(xroot)
xslt_root = etree.XML('''
     <xsl:stylesheet version="1.0"
         xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
         <xsl:template match="xml">
             <div id='name'><xsl:value-of select="name" /></div>
             <div id='surname'><xsl:value-of select="surname" /></div>
         </xsl:template>
 </xsl:stylesheet>''')
# transform = etree.XSLT(xslt_root)
transform = etree.XSLT(xslt_root)
# html = etree.tostring(transform(xml)).decode('utf-8')
# print(html)
print(str(transform(xml)).split('\n'))
# ['<?xml version="1.0"?>', '<div id="name">donald</div><div id="surname">trump</div>', '']
# the element at index 1 contains <div id="name">donald</div><div id="surname">trump</div>