我一直在绞尽脑汁,但似乎无法做到正确,而且我没有在谷歌上找到正确的关键词..
我最近开始使用XSLT和XPath来创建自然语言词汇表的XML描述 - 用于我的项目。
问题在于我选择对某些单词使用“混合内容”复杂元素,并且在某些情况下只想获取文本节点。
以下是XML文档的一部分:
...
<entry category="substantiv">
<word lang="sv">semester</word>
<word lang="de">
<article>der</article>Urlaub
<plural>Urlaube</plural>
</word>
</entry>
...
我的文档中有许多入口元素,在这个例子中,我想使用:/entry/word[@lang='de']/text()
来获取'Urlaub',因为我的换行符不起作用。我发现实际上有三个文本节点.. .../text()[2]
当然会工作..但是,我事先不知道哪里会有换行符,或者有多少行。如果xml的格式如下,我的第一个版本的路径将起作用,但不是第二个:
...
<word lang="de"><article>der</article>Urlaub
<plural>Urlaube</plural>
</word>
...
我认为我想要做的是选择单词[@ lang ='de']的所有直接文本节点,然后使用normalize-space()
删除不必要的空白区域。但是,如何使用XPath执行此操作?或者,还有更好的方法?这似乎很容易,但我无法弄清楚。我正在尝试在XSLT文档中执行此操作。
normalize-space(/entry/word[@lang='de']/text()[*])
是我尝试过的事情之一,但这似乎做了别的事情。
/感谢任何帮助。
更新
根据要求,这是XSLT的一部分:
...
<xsl:choose>
<xsl:when test="@category='substantiv'">
<em><xsl:value-of select="word[@lang='de']/article" /></em>
<xsl:value-of select="normalize-space(word[@lang='de']/text()[2])" />
<em>pl. <xsl:value-of select="word[@lang='de']/plural" /></em>
</xsl:when>
...
此代码适用于第一版格式化。为了澄清,我想要做的是绘制复杂元素<word lang="de">
中的文本节点的值,尽管它可能使用换行符和空格格式化。我将对该值做什么取决于上下文,但现在我将它放在一个xhtml文档中。
UPDATE2:
我现在使用<xsl:strip-space elements="*"/>
,这消除了空文本节点的问题。我也在使用:
...
<xsl:choose>
<xsl:when test="@category='substantiv'">
<em><xsl:value-of select="word[@lang='de']/article" /></em>
<xsl:text> </xsl:text>
<xsl:value-of select="normalize-space(word[@lang='de']/text())" />
<xsl:text>, </xsl:text>
<em>pl. <xsl:value-of select="word[@lang='de']/plural" /></em>
</xsl:when>
...
仍需要规范化,因为在XML中的“Urlaub”之后仍然添加了空格。
当我需要在XSLT文档之外到达文本节点“Urlaub”时,我使用:
<xsl:value-of select="normalize-space(word[@lang='de']/text()[normalize-space() != ''])" />
感谢所有帮助人员!
更新3: 试图改善标题
答案 0 :(得分:2)
这种转变:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<xsl:value-of select="/*/entry/word[@lang='de']/text()[1]"/>
</xsl:template>
</xsl:stylesheet>
应用于提供的XML文档(包含在dict
顶部元素中):
<dict>
<entry category="substantiv">
<word lang="sv">semester</word>
<word lang="de">
<article>der</article>Urlaub
<plural>Urlaube</plural>
</word>
</entry>
</dict>
产生完全想要的结果:
Urlaub
请注意:使用<xsl:strip-space>
指令从源XML文档中删除所有仅限空格的文本节点。
因此,无需额外处理(normalize-space()等)。
答案 1 :(得分:0)
现在我看到你的代码了,我推荐这个:
<xsl:choose>
<xsl:when test="@category='substantiv'">
<em><xsl:value-of select="word[@lang='de']/article" /></em>^
<!-- select the first non-empty text node and normalize it -->
<xsl:value-of select="normalize-space(word[@lang='de']/text()[normalize-space() != ''][1])" />
<em>pl. <xsl:value-of select="word[@lang='de']/plural" /></em>
</xsl:when>
答案的原始版本
为了帮助您入门:
<entry category="substantiv">
<word lang="sv">semester</word>
<word lang="de">
<article>der</article>Urlaub
<plural>Urlaube</plural>
</word>
</entry>
通过此XSLT 1.0时:
<!-- identity template copies everything 1:1, unless other templates apply -->
<xsl:template match="*|@*">
<xsl:copy>
<xsl:apply-templates select="*|@*" />
</xsl:copy>
</xsl:template>
<!-- empty template: ignore every white-space-only text-node child of <word> -->
<xsl:template match="word/text()[normalize-space() = '']" />
会产生这个:
<entry category="substantiv">
<word lang="sv">semester</word>
<word lang="de"><article>der</article>Urlaub<plural>Urlaube</plural></word>
</entry>
这个答案是一个猜测,可能不完全是你所追求的。无论如何,您的问题需要澄清。并不总是你想要你想要的实际想要的东西。
答案 2 :(得分:0)
尝试:
/entry/word[@lang='de']/child::text()[normalize-space(.) != '']
意思是,抓住所有子文本节点,但不抓取那些规范化为空字符串的节点。
-Oisin
答案 3 :(得分:0)
我认为这是你想要的骨架,减去任何normalize-space(),让事情看起来完全符合你想要的。
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="/">
<xsl:apply-templates select=".//word"/>
</xsl:template>
<xsl:template match="word">
<xsl:apply-templates select=".//text()"/>
</xsl:template>
<xsl:template match="text()"><xsl:value-of select="."/><xsl:text> </xsl:text></xsl:template>
</xsl:stylesheet>
键是.//text()
,它返回上下文节点()下面任何嵌套级别的所有子文本节点的串联。