英文:
select xsl:variable values of its child-nodes
问题
以下是代码部分的中文翻译:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0"
xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0"
xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0"
xmlns:exsl="http://exslt.org/common"
exclude-result-prefixes="table text office exsl"
>
<xsl:output
method="xml"
indent="yes"
encoding="UTF-8"
omit-xml-declaration="no"
/>
<xsl:template match="/">
<xsl:variable name="columnHeadings-temp" xmlns="">
<xsl:for-each select="//table:table/table:table-row[not(preceding::table:table-row)]//table:table-cell">
<xsl:element name="heading">
<xsl:attribute name="name">
<xsl value-of select="normalize-space(text:p)" />
</xsl:attribute>
<xsl:value-of select="position()" />
</xsl:element>
</xsl:for-each>
</xsl:variable>
<xsl:variable name="columnHeadings" select="exsl:node-set($columnHeadings-temp)" />
<html>
<body>
<table>
<xsl:for-each select="//table:table/table:table-row">
<xsl:if test="position() > 1">
<tr>
<td>
First Column Value
<xsl:value-of select="table:table-cell[number($columnHeadings/heading[@name='First_Name'])]/text:p" />
</td>
<td>
Second Column Value
<xsl:value-of select="table:table-cell[number($columnHeadings/heading[@name='Last_Name'])]/text:p" />
</td>
</tr>
</xsl:if>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
希望这对你有所帮助。如果你有任何其他问题或需要进一步的帮助,请随时提出。
英文:
I have an .ods file and want to access the values of table-cell
s in table-row
s by the value of the first column for the given row. So their heading in my case.
So the calc table looks like this:
First_Name | Last_Name
Peter | Parker
Emma | Stone
...
Here is my xslt-export-filter file:
SuperBasicExportFilter.xslt
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0"
xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0"
xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0"
exclude-result-prefixes="table text office"
>
<xsl:output
method="xml"
indent="yes"
encoding="UTF-8"
omit-xml-declaration="no"
/>
<xsl:template match="/">
<xsl:variable name="columnHeadings">
<xsl:for-each select="//table:table/table:table-row[not(preceding::table:table-row)]//table:table-cell">
<xsl:element name="heading">
<xsl:attribute name="name" select="text:p" />
<xsl:value-of select="position()" />
</xsl:element>
</xsl:for-each>
</xsl:variable>
<html>
<body>
<h1>Hello</h1>
<xsl:message>columnHeadings: <xsl:value-of select="$columnHeadings" /></xsl:message>
<table>
<xsl:for-each select="//table:table/table:table-row">
<xsl:if test="position() > 1">
<tr>
<td>
First Column Value
<xsl:value-of select="table:table-cell[1]/text:p" />
<!-- <xsl:value-of select="table:table-cell[$columnHeadings/heading[@name='First_Name']]/text:p" /> -->
</td>
<td>
Second Column Value
<xsl:value-of select="table:table-cell[2]/text:p" />
<!-- <xsl:value-of select="table:table-cell[$columnHeadings/heading[@name='Last_Name']]/text:p" /> -->
</td>
</tr>
</xsl:if>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
The message shows "columnHeadings: 1234567891011121314" and so on. So it is setting the position values correctly.
I tried getting the values based on the "name" attribute on the "heading" element.
But I can't get the values individually in any way. It seems I can't use the $columnHeadings with any XPath expression. It just returns "Xpath evaluation returned no result".
I tried
- wrapping the "heading" elements with a "columnHeadings" element inside the variable and setting the "as" value of the variable to "element()"
- using the "node-set" function (after importing the "exslt" ns)
- using
<xsl:variable name="columnHeadingsNode" select="document('')//xsl:variable[@name = 'columnHeadings']" />
to then get the value - using the
xsl:key
element like<xsl:key name="columnHeadings" match="//table:table/table:table-row[not(preceding::table:table-row)]//table:table-cell" use="text:p" />
- but this way I can't access it based on the "name"
What other things can I try to access the variable contents with a xpath expression?
Is it even possible to access the values like table:table-cell[$columnHeadings/heading[@name='Last_Name']]
?
Answers to comments:
> Which XSLT processor are you using?
I'm using whatever libreoffice 7.4.5.1 is using.
Can I change that?
The xsl:vendor is "libxslt" and the version is "1.0" according to the <xsl:value-of select="system-property('xsl:vendor')"/>
and xsl:version
values.
> Do you get an error on <xsl:attribute name="name" select="text:p" />
?
I actually do not for some reason. The test runs through without errors. I get a new browser tab with the produced xml output and no errors.
I tried ticking the "The filter needs XSLT 2.0 processor" but then I can't test run the filter anymore and don't get any output.
> What's the overall purpose of this exercise?
I want to be able to select the values in the columns by their respective column heading, instead of the index, because I want to make it as portable as possible. At least I think that would help to achieve that goal. I have 184 columns. The column names won't change as likely as the index of the column, I believe.
SOLVED
My working file looks like this now:
SuperBasicExportFilter.xslt
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0"
xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0"
xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0"
xmlns:exsl="http://exslt.org/common"
exclude-result-prefixes="table text office exsl"
>
<xsl:output
method="xml"
indent="yes"
encoding="UTF-8"
omit-xml-declaration="no"
/>
<xsl:template match="/">
<xsl:variable name="columnHeadings-temp" xmlns="">
<xsl:for-each select="//table:table/table:table-row[not(preceding::table:table-row)]//table:table-cell">
<xsl:element name="heading">
<xsl:attribute name="name">
<xsl value-of select="normalize-space(text:p)" />
</xsl:attribute>
<xsl:value-of select="position()" />
</xsl:element>
</xsl:for-each>
</xsl:variable>
<xsl:variable name="columnHeadings" select="exsl:node-set($columnHeadings-temp)" />
<html>
<body>
<table>
<xsl:for-each select="//table:table/table:table-row">
<xsl:if test="position() > 1">
<tr>
<td>
First Column Value
<xsl:value-of select="table:table-cell[number($columnHeadings/heading[@name='First_Name'])]/text:p" />
</td>
<td>
Second Column Value
<xsl:value-of select="table:table-cell[number($columnHeadings/heading[@name='Last_Name'])]/text:p" />
</td>
</tr>
</xsl:if>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
答案1
得分: 1
以下是翻译好的部分:
意图 <xsl:attribute name="name" select="text:p" />
在 XSLT 1 中无法创建具有值的属性;它应该引发错误,但似乎您的 XSLT 处理器有点忽略了 select
。
所以尝试使用:
<xsl:attribute name="name">
<xsl:value-of select="text:p"/>
</xsl:attribute>
替代。
这样,我认为例如 <xsl:variable name="columnHeadings-ns" select="exsl:node-set($columnHeadings)" xmlns:exsl="http://exslt.org/common"/>
应该允许您使用例如 <xsl:value-of select="table:table-cell[$columnHeadings-ns/heading[@name='First_Name']]/text:p"/>
。
英文:
The intent <xsl:attribute name="name" select="text:p" />
fails to create an attribute with a value in XSLT 1; it should raise an error but it seems your XSLT processor kind of ignores the select
.
So try
<xsl:attribute name="name">
<xsl:value-of select="text:p"/>
</xsl:attribute>
instead.
That way, I would think that e.g. <xsl:variable name="columnHeadings-ns" select="exsl:node-set($columnHeadings)" xmlns:exsl="http://exslt.org/common"/>
should allow you to use e.g. <xsl:value-of select="table:table-cell[$columnHeadings-ns/heading[@name='First_Name']]/text:p"/>
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论