Python idref() 的 lxml 问题?
Python lxml problems with idref()?
大家好,不幸的是我遇到了 XSLT 或 Python XML 解析器 lxml 的问题。我有一个经过验证的 DTD XML,我想使用 XSLT 来查找 ID 的所有 IDREF。下面是示例 XML 和 XSLT。
XML 1.0
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE TEST
[
<!ELEMENT TEST (N*,SUB*)>
<!ELEMENT N (#PCDATA)>
<!ELEMENT SUB (E*)>
<!ELEMENT E (#PCDATA)>
<!ATTLIST TEST
>
<!ATTLIST SUB
>
<!ATTLIST N
Id ID #REQUIRED
X CDATA #REQUIRED
>
<!ATTLIST E
EID ID #REQUIRED
N1 IDREF #REQUIRED
N2 IDREF #REQUIRED
>
]>
<TEST>
<N Id="N1" X="0.0"/>
<N Id="N2" X="1.0"/>
<N Id="N3" X="2.0"/>
<N Id="N4" X="3.0"/>
<SUB>
<E EID="E1" N1="N1" N2="N2"/>
<E EID="E2" N1="N1" N2="N3"/>
<E EID="E3" N1="N1" N2="N4"/>
</SUB>
</TEST>
XSLT 1.0 (
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:output method="xml"/>
<xsl:strip-space elements="*"/>
<xsl:template match="//N">
<xsl:element name="NREF">
<xsl:for-each select="**idref('N1')**">
<xsl:value-of select="name()"/>
</xsl:for-each>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
我的示例 python 脚本解析 XML 和 XSLT,转换 XML 并将结果写入新文件。
Python3.9
import lxml
from lxml import etree
import xml.etree.ElementTree as ET
xml_parser = lxml.etree.XMLParser( attribute_defaults=True, dtd_validation =True, no_network=False)
xml_root = lxml.etree.parse('XML.xml', parser=xml_parser)
xslt_root = lxml.etree.parse('id_idref_test.xslt')
transform = etree.XSLT(xslt_root)
result_tree = transform(xml_root)
result_tree.write(f"XML_Result.xml",method="xml",pretty_print=True)
现在谈谈我的问题。 Xpath 支持函数 id()
和 idref()
。当我在循环中使用 id('N1')
函数时,我得到以下结果。<NREF>N</NREF>
。如果我使用 idref('N1')
函数,我会从解析器中得到一个错误。 lxml.etree.XSLTApplyError: Failed to evaluate the 'select' expression.
idref()
功能是否未在 lxml 范围内实现?
我希望我能足够详细地解释我的问题。感谢您的帮助。
idref() 函数需要 XPath/XSLT 2.0 或更高版本。 感谢 michael.hor257k
大家好,不幸的是我遇到了 XSLT 或 Python XML 解析器 lxml 的问题。我有一个经过验证的 DTD XML,我想使用 XSLT 来查找 ID 的所有 IDREF。下面是示例 XML 和 XSLT。
XML 1.0
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE TEST
[
<!ELEMENT TEST (N*,SUB*)>
<!ELEMENT N (#PCDATA)>
<!ELEMENT SUB (E*)>
<!ELEMENT E (#PCDATA)>
<!ATTLIST TEST
>
<!ATTLIST SUB
>
<!ATTLIST N
Id ID #REQUIRED
X CDATA #REQUIRED
>
<!ATTLIST E
EID ID #REQUIRED
N1 IDREF #REQUIRED
N2 IDREF #REQUIRED
>
]>
<TEST>
<N Id="N1" X="0.0"/>
<N Id="N2" X="1.0"/>
<N Id="N3" X="2.0"/>
<N Id="N4" X="3.0"/>
<SUB>
<E EID="E1" N1="N1" N2="N2"/>
<E EID="E2" N1="N1" N2="N3"/>
<E EID="E3" N1="N1" N2="N4"/>
</SUB>
</TEST>
XSLT 1.0 (
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:output method="xml"/>
<xsl:strip-space elements="*"/>
<xsl:template match="//N">
<xsl:element name="NREF">
<xsl:for-each select="**idref('N1')**">
<xsl:value-of select="name()"/>
</xsl:for-each>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
我的示例 python 脚本解析 XML 和 XSLT,转换 XML 并将结果写入新文件。
Python3.9
import lxml
from lxml import etree
import xml.etree.ElementTree as ET
xml_parser = lxml.etree.XMLParser( attribute_defaults=True, dtd_validation =True, no_network=False)
xml_root = lxml.etree.parse('XML.xml', parser=xml_parser)
xslt_root = lxml.etree.parse('id_idref_test.xslt')
transform = etree.XSLT(xslt_root)
result_tree = transform(xml_root)
result_tree.write(f"XML_Result.xml",method="xml",pretty_print=True)
现在谈谈我的问题。 Xpath 支持函数 id()
和 idref()
。当我在循环中使用 id('N1')
函数时,我得到以下结果。<NREF>N</NREF>
。如果我使用 idref('N1')
函数,我会从解析器中得到一个错误。 lxml.etree.XSLTApplyError: Failed to evaluate the 'select' expression.
idref()
功能是否未在 lxml 范围内实现?
我希望我能足够详细地解释我的问题。感谢您的帮助。
idref() 函数需要 XPath/XSLT 2.0 或更高版本。 感谢 michael.hor257k