我遇到了XSLT混合命名空间的问题。我想为命名空间“doc”中的不同项目创建一些共享模板,并从名称空间“map”中调用它们,但这不起作用。有没有办法做到这一点?
map.xml:
<?xml version="1.0"?>
<root xmlns="http://www.example.com/map"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.example.com/map map.xsd">
<node>
<short>Short description</short>
<long>Long description <br/> needs a lot of space</long>
</node>
<node>
<short>Another short description</short>
<long>Another long description <br/> also needs a lot of space_</long>
</node>
</root>
map.xsd
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.example.com/map"
xmlns:tns="http://www.example.com/map"
xmlns:doc="http://www.example.com/doc"
elementFormDefault="qualified">
<import namespace="http://www.example.com/doc" schemaLocation="doc.xsd"/>
<element name="root">
<complexType>
<sequence>
<element name="node" minOccurs="1" maxOccurs="unbounded">
<complexType>
<sequence>
<element name="short" type="normalizedString" />
<element name="long">
<complexType mixed="true">
<sequence>
<choice minOccurs="0" maxOccurs="unbounded">
<element ref="doc:br" />
</choice>
</sequence>
</complexType>
</element>
</sequence>
</complexType>
</element>
</sequence>
</complexType>
</element>
<!-- make imported elements from documentation public available -->
<element name="br" substitutionGroup="doc:br"/>
</schema>
doc.xsd:
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.example.com/doc"
xmlns:tns="http://www.example.com/doc"
elementFormDefault="qualified">
<element name="br"></element>
</schema>
xml文件使用此架构文件进行验证。
map.xsl:
<?xml version="1.0"?>
<xsl:transform version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.w3.org/1999/XSL/Transform http://www.w3.org/2007/schema-for-xslt20.xsd"
xmlns:doc="http://www.example.com/doc"
xmlns:map="http://www.example.com/map" >
<xsl:import href="doc.xsl" />
<!-- output method is .tex file, no xml -->
<xsl:output method="text" media-type="application/x-tex" indent="no"/>
<xsl:template match="map:root">
<xsl:text>\begin{Root}{
</xsl:text>
<xsl:apply-templates select="map:node" />
<xsl:text>\end{Root}</xsl:text>
</xsl:template>
<xsl:template match="map:node">
<xsl:text>\begin{Node}
{</xsl:text>
<xsl:apply-templates select="map:short" />
<xsl:text>}
</xsl:text>
<xsl:apply-templates select="map:long" />
<xsl:text>
\end{Node}
</xsl:text>
</xsl:template>
<xsl:template match="map:short">
<xsl:apply-templates select="text()" />
</xsl:template>
<xsl:template match="map:long">
<xsl:apply-templates select="text() | doc:br" />
</xsl:template>
</xsl:transform>
doc.xsl:
<?xml version="1.0"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.w3.org/1999/XSL/Transform http://www.w3.org/2007/schema-for-xslt20.xsd"
xmlns:doc="http://www.example.com/doc" >
<xsl:template match="doc:br">
<xsl:text> \\
</xsl:text>
</xsl:template>
<!-- copy unspecific text, escape before -->
<xsl:template match="text()">
<xsl:copy-of select="normalize-space(replace(., '(&|%|\$|#|_)', '\\$1'))" />
</xsl:template>
</xsl:stylesheet>
使用此模板,转换有效,但不会产生病变输出。
生成输出:
\begin{Root}{
\begin{Node}
{Short description}
Long description needs a lot of space
\end{Node}
\begin{Node}
{Another short description}
Another long description also needs a lot of space\_
\end{Node}
\end{Root}
期望的输出:
\begin{Root}{
\begin{Node}
{Short description}
Long description needs a lot of space
\end{Node}
\begin{Node}
{Another short description}
Another long description also \\
needs a lot of space\_
\end{Node}
\end{Root}
答案 0 :(得分:1)
根据您的map.xml
输入文档,该文档中的所有元素都位于同一名称空间http://www.example.com/map
中,包括br
元素。因此,我不明白为什么导入的样式表与不同命名空间中的br
元素匹配应该有助于该输入文档。如果要转换这些元素,则需要编写匹配map:br
的模板。
答案 1 :(得分:0)
根据XSLT include with different namespaces我修改了doc.xsl:
<?xml version="1.0"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.w3.org/1999/XSL/Transform http://www.w3.org/2007/schema-for-xslt20.xsd"
xmlns:doc="http://www.example.com/doc" >
<xsl:template match="*:br">
<xsl:text> \\
</xsl:text>
</xsl:template>
<!-- copy unspecific text, escape before -->
<xsl:template match="text()">
<xsl:copy-of select="normalize-space(replace(., '(&|%|\$|#|_)', '\\$1'))" />
</xsl:template>
</xsl:stylesheet>
另一种可能性是使用命名模板,然后按照他的建议从主xsl文件中调用它们。