XSLT 从 docx document.xml 中读取了 Table 的内容
XSLT read Table of contents from docx document.xml
我正在尝试使用 XSLT
从 docx 的 document.xml 文件中检索目录
这是我的 XSLT:
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:sap="http://www.sap.com/sapxsl" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" exclude-result-prefixes="w" version="2.0">
<xsl:output indent="yes" method="xml"/>
<xsl:strip-space elements="*"/>
<xsl:template match="w:sdt">
<xsl:element name="root">
<xsl:attribute name="label">
<xsl:value-of select="w:sdtPr/w:docPartObj/w:docPartGallery/@w:val"/>
</xsl:attribute>
<xsl:for-each select="w:sdtContent/w:p">
<xsl:if test="w:pPr/w:pStyle/@w:val">
<xsl:element name="sec">
<xsl:attribute name="label">
<xsl:value-of select="w:pPr/w:pStyle/@w:val"/>
</xsl:attribute>
<xsl:attribute name="anchor">
<xsl:value-of select="w:hyperlink/@w:anchor"/>
</xsl:attribute>
<xsl:attribute name="title">
<xsl:value-of select="w:hyperlink/w:r/w:t"/>
</xsl:attribute>
</xsl:element>
</xsl:if>
</xsl:for-each>
</xsl:element>
</xsl:if>
</xsl:template>
</xsl:transform>
我得到了想要的结果,但是 w:p 标签值超出了 w:sdtContent 范围。
我是 XSLT 的初学者,不确定我做错了什么。
(如果来源 xml 有帮助,请告诉我我会 post 在这里。)
XSLT 使用 a set of default rules 从根节点开始处理其输入。这些默认规则可以被覆盖——但你不能那样做。我怀疑您看到的不需要的额外输出来自默认规则。
您的样式表包含一个模板 <xsl:template match="w:sdt">
并且 XSLT 处理器 执行 运行 该模板,但仅当它到达 <w:sdt>
当它遍历输入文档时。
如果您想自己从根节点开始并指示 XSLT 处理器应该查看哪些节点,请通过编写与根节点匹配的模板来覆盖默认行为 ( <xsl:template match="/">
).
<xsl:transform
version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:sap="http://www.sap.com/sapxsl"
xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"
exclude-result-prefixes="w"
>
<xsl:output indent="yes" method="xml" />
<xsl:strip-space elements="*" />
<xsl:template match="/">
<xsl:apply-temmplates select="//w:sdt" />
</xsl:template>
<xsl:template match="w:sdt">
<root label="{w:sdtPr/w:docPartObj/w:docPartGallery/@w:val}" />
<xsl:apply-templates select="w:sdtContent/w:p[w:pPr/w:pStyle/@w:val]" />
</root>
</xsl:template>
<xsl:template match="w:sdtContent/w:p">
<sec
label="{w:pPr/w:pStyle/@w:val}"
anchor="{w:hyperlink/@w:anchor}"
title="{w:hyperlink/w:r/w:t}"
/>
</xsl:template>
</xsl:transform>
其他说明:
- 不要写
<xsl:element name="foo">
。写入 <foo>
.
- 不写
<xsl:attribute name="bar">
写<foo bar="{xpath-expr}">
.
- 避免
<xsl:for-each>
。使用 <xsl:apply-templates>
和 <xsl:template>
.
- 避免使用
<xsl:if>
过滤您要处理的节点。编写一个适当的 XPath 表达式,只选择您要处理的节点。
- 可能有帮助的阅读:How
<xsl:apply-templates>
works。
我正在尝试使用 XSLT
从 docx 的 document.xml 文件中检索目录这是我的 XSLT:
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:sap="http://www.sap.com/sapxsl" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" exclude-result-prefixes="w" version="2.0">
<xsl:output indent="yes" method="xml"/>
<xsl:strip-space elements="*"/>
<xsl:template match="w:sdt">
<xsl:element name="root">
<xsl:attribute name="label">
<xsl:value-of select="w:sdtPr/w:docPartObj/w:docPartGallery/@w:val"/>
</xsl:attribute>
<xsl:for-each select="w:sdtContent/w:p">
<xsl:if test="w:pPr/w:pStyle/@w:val">
<xsl:element name="sec">
<xsl:attribute name="label">
<xsl:value-of select="w:pPr/w:pStyle/@w:val"/>
</xsl:attribute>
<xsl:attribute name="anchor">
<xsl:value-of select="w:hyperlink/@w:anchor"/>
</xsl:attribute>
<xsl:attribute name="title">
<xsl:value-of select="w:hyperlink/w:r/w:t"/>
</xsl:attribute>
</xsl:element>
</xsl:if>
</xsl:for-each>
</xsl:element>
</xsl:if>
</xsl:template>
</xsl:transform>
我得到了想要的结果,但是 w:p 标签值超出了 w:sdtContent 范围。
我是 XSLT 的初学者,不确定我做错了什么。
(如果来源 xml 有帮助,请告诉我我会 post 在这里。)
XSLT 使用 a set of default rules 从根节点开始处理其输入。这些默认规则可以被覆盖——但你不能那样做。我怀疑您看到的不需要的额外输出来自默认规则。
您的样式表包含一个模板 <xsl:template match="w:sdt">
并且 XSLT 处理器 执行 运行 该模板,但仅当它到达 <w:sdt>
当它遍历输入文档时。
如果您想自己从根节点开始并指示 XSLT 处理器应该查看哪些节点,请通过编写与根节点匹配的模板来覆盖默认行为 ( <xsl:template match="/">
).
<xsl:transform
version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:sap="http://www.sap.com/sapxsl"
xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"
exclude-result-prefixes="w"
>
<xsl:output indent="yes" method="xml" />
<xsl:strip-space elements="*" />
<xsl:template match="/">
<xsl:apply-temmplates select="//w:sdt" />
</xsl:template>
<xsl:template match="w:sdt">
<root label="{w:sdtPr/w:docPartObj/w:docPartGallery/@w:val}" />
<xsl:apply-templates select="w:sdtContent/w:p[w:pPr/w:pStyle/@w:val]" />
</root>
</xsl:template>
<xsl:template match="w:sdtContent/w:p">
<sec
label="{w:pPr/w:pStyle/@w:val}"
anchor="{w:hyperlink/@w:anchor}"
title="{w:hyperlink/w:r/w:t}"
/>
</xsl:template>
</xsl:transform>
其他说明:
- 不要写
<xsl:element name="foo">
。写入<foo>
. - 不写
<xsl:attribute name="bar">
写<foo bar="{xpath-expr}">
. - 避免
<xsl:for-each>
。使用<xsl:apply-templates>
和<xsl:template>
. - 避免使用
<xsl:if>
过滤您要处理的节点。编写一个适当的 XPath 表达式,只选择您要处理的节点。 - 可能有帮助的阅读:How
<xsl:apply-templates>
works。