XSLT 1.0 和标记属性
[编辑]帖子更新了修订后的 XML 和所需的输出,如 Vincent Biragnet 的答案和评论中详细介绍的。
我正在尝试组合一些代码以将 XML 数据转换为基于文本的元文件。我没有运气让它吐出所需的输出,并且目前有点卡住,所以任何帮助将不胜感激。
XSLT 1.0 并没有使标记化变得容易,这就是我陷入困境的地方:我想将 @syn 视为 CSV 字符串,并在需要时将其分开。
我正在使用以下 XML 数据(请注意,此 XML 文件中除
节点外的所有节点都可以具有任何名称。)<Meta>
<Subject>
<People>
<Jane_Doe syn="janie, jd" />
<John_Doe/>
</People>
<Object>
<Table>
<Leg/>
</Table>
<Chair syn="seat" />
</Object>
</Subject>
<Test1>
<Test2 syn="testy"/>
<Test3>
<Test4/>
</Test3>
</Test1>
</Meta>
需要转换此 XML,以便输出如下所示:
[Subject]
[People]
Jane_Doe
{janie}
{jd}
John_Doe
[Object]
[Table]
Leg
Chair
{seat}
[Test1]
Test2
{testy}
[Test3]
Test4
My current XSL :
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="text" indent="yes"/>
<xsl:template match="/Meta"><xsl:apply-templates/></xsl:template>
<xsl:template match="child::*"><xsl:call-template name="master"/><xsl:apply-templates/></xsl:template>
<xsl:template name="master">
<xsl:choose>
<xsl:when test="count(child::*) = 0">
<xsl:value-of select="local-name()"/>
<xsl:apply-templates select="@syn"/>
</xsl:when>
<xsl:otherwise>
[<xsl:value-of select="local-name()"/>]
<xsl:apply-templates select="@syn"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="tokenize" match="@syn">
<xsl:param name="text" select="."/>
<xsl:param name="separator" select="','"/>
<xsl:value-of select="$text"/>
<xsl:choose>
<xsl:when test="not(contains($text, $separator))">
{<xsl:value-of select="normalize-space($text)"/>}
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="normalize-space(substring-before($text, $separator))"/>
<xsl:call-template name="tokenize">
{<xsl:with-param name="text" select="substring-after($text, $separator)"/>}
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
[edit] post updated with revised XML and desired output as detailed in Vincent Biragnet's answer and comments.
I'm trying to put together some code to convert XML data into a text based meta file. I'm having no luck getting it to spit out desired output and am currently kinda stuck, so any help would be appreciated.
XSLT 1.0 does not make tokenizing easy and that's where I got stuck: I would like to treat @syn as a CSV string and break it apart when needed.
I'm working with the following XML data (please note that all nodes, except for the <Meta> node, in this XML file can have any name.)
<Meta>
<Subject>
<People>
<Jane_Doe syn="janie, jd" />
<John_Doe/>
</People>
<Object>
<Table>
<Leg/>
</Table>
<Chair syn="seat" />
</Object>
</Subject>
<Test1>
<Test2 syn="testy"/>
<Test3>
<Test4/>
</Test3>
</Test1>
</Meta>
This XML needs to be converted so the output looks this:
[Subject]
[People]
Jane_Doe
{janie}
{jd}
John_Doe
[Object]
[Table]
Leg
Chair
{seat}
[Test1]
Test2
{testy}
[Test3]
Test4
My current XSL:
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="text" indent="yes"/>
<xsl:template match="/Meta"><xsl:apply-templates/></xsl:template>
<xsl:template match="child::*"><xsl:call-template name="master"/><xsl:apply-templates/></xsl:template>
<xsl:template name="master">
<xsl:choose>
<xsl:when test="count(child::*) = 0">
<xsl:value-of select="local-name()"/>
<xsl:apply-templates select="@syn"/>
</xsl:when>
<xsl:otherwise>
[<xsl:value-of select="local-name()"/>]
<xsl:apply-templates select="@syn"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="tokenize" match="@syn">
<xsl:param name="text" select="."/>
<xsl:param name="separator" select="','"/>
<xsl:value-of select="$text"/>
<xsl:choose>
<xsl:when test="not(contains($text, $separator))">
{<xsl:value-of select="normalize-space($text)"/>}
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="normalize-space(substring-before($text, $separator))"/>
<xsl:call-template name="tokenize">
{<xsl:with-param name="text" select="substring-after($text, $separator)"/>}
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
使用 XSLT 1.0 准确地获得输出有点棘手,但您可以使用您尝试过的机制。下面是一个带有缩进输出的 XSLT 1.0:
您输入的结果是:
请注意与您的输出的区别:
table
元素位于括号之间,因为它有一个或多个子元素。It's a bit tricky to get exactly your output with XSLT 1.0, but you can use the mecanism you tried. Here is an XSLT 1.0 that output with the indentation :
The result with your input is :
Note the difference with your output : the
table
element is between bracket because it has one or more children.你几乎就在那里,只是用括号括住错误的东西导致错误!
you were pretty much there, just got brackets around wrong thing causing error!
我会这样做:
I would do it like this: