xml 到 xsl 中的子字符串
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5041115/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
To Substring in xsl
提问by Vignesh Lakshmanan
Hi I am converting one XML to another XML using XSL.
嗨,我正在使用 XSL 将一个 XML 转换为另一个 XML。
The problem I face is the value inside the tag is 10feb2011i.e <date>10feb2011</date>.
我面临的问题是标签内的值是10feb2011ie <date>10feb2011</date>。
I need the output to be:
我需要输出为:
<date>10</date>
<month>feb</month>
<year>2011</year>
so I used substringfunction, but could not get it to work.
所以我使用了substring函数,但无法让它工作。
My XML looks like
我的 XML 看起来像
<ArrivalDateTime>
<Date>20feb2011<Date>
</ArrivalDateTime>
It should be converted into this format
应该转换成这种格式
<ArrivalDateTime>
<dayOfMonth>10</dayOfMonth>
<month>feb</month>
<year>2011</year>
</ArrivalDateTime>
Below is the XSL I wrote
下面是我写的XSL
<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- Edited by XMLSpy? -->
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<xsl:text><![CDATA[<ArrivalDateTime>]]></xsl:text>
<xsl:text><![CDATA[<dayOfMonth>]]></xsl:text>
<xsl:value-of select='substring("<xsl:value-of select="/ArrivalDateTime/Date"/>",1,2)'/>
<xsl:text><![CDATA[</dayOfMonth>]]></xsl:text>
<xsl:text><![CDATA[<month>]]></xsl:text>
<xsl:value-of select='substring("<xsl:value-of select="/ArrivalDateTime/Date"/>",3,3)'/>
<xsl:text><![CDATA[</month>]]></xsl:text>
<xsl:text><![CDATA[<year>]]></xsl:text>
<xsl:value-of select='substring("<xsl:value-of select="/ArrivalDateTime/Date"/>",5,4)'/>
<xsl:text><![CDATA[</year>]]></xsl:text>
<xsl:text><![CDATA[</ArrivalDateTime>]]></xsl:text></xsl:template>
</xsl:stylesheet>
回答by Dirk Vollmar
Your XSLT looks overly complicated. Simply create the XML nodes like that:
您的 XSLT 看起来过于复杂。只需像这样创建 XML 节点:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<ArrivalDateTime>
<dayOfMonth>
<xsl:value-of select="substring(/ArrivalDateTime/Date,1,2)"/>
</dayOfMonth>
<month>
<xsl:value-of select="substring(/ArrivalDateTime/Date,3,3)"/>
</month>
<year>
<xsl:value-of select="substring(/ArrivalDateTime/Date,5,4)"/>
</year>
</ArrivalDateTime>
</xsl:template>
</xsl:stylesheet>
You shouldn't be using CDATA sections to create XML nodes in your output document. This is unnecessary and potentially dangerous as it allows the generation of invalid XML.
您不应该使用 CDATA 部分在输出文档中创建 XML 节点。这是不必要的并且有潜在危险,因为它允许生成无效的 XML。
Please note as well that inside XPath expressions such as within the selectattributes you must write valid XPath. XML tags are not allowed here.
还请注意,在 XPath 表达式中,例如在select属性中,您必须编写有效的 XPath。此处不允许使用 XML 标记。
Best to check some XSLT tutorial to get started.
最好查看一些 XSLT 教程以开始使用。
回答by dogbane
Your substring syntax isn't completely correct. You need to use 6,4 (not 5,4) for the year substring. Also you don't need to use xsl:textto emit xml tags.
您的子字符串语法不完全正确。您需要使用 6,4(而不是 5,4)作为年份子字符串。您也不需要使用xsl:text来发出 xml 标签。
Try this instead:
试试这个:
<xsl:template match="/">
<ArrivalDateTime>
<dayOfMonth>
<xsl:value-of select="substring(/ArrivalDateTime/Date,1,2)"/>
</dayOfMonth>
<month>
<xsl:value-of select="substring(/ArrivalDateTime/Date,3,3)"/>
</month>
<year>
<xsl:value-of select="substring(/ArrivalDateTime/Date,6,4)"/>
</year>
</ArrivalDateTime>
</xsl:template>
Alternative:
选择:
You can even use a variable to hold the date, which is a bit neater:
你甚至可以使用一个变量来保存日期,这样更简洁一点:
<xsl:template match="/">
<xsl:variable name="mydate" select="/ArrivalDateTime/Date" />
<ArrivalDateTime>
<dayOfMonth>
<xsl:value-of select="substring($mydate,1,2)"/>
</dayOfMonth>
<month>
<xsl:value-of select="substring($mydate,3,3)"/>
</month>
<year>
<xsl:value-of select="substring($mydate,6,4)"/>
</year>
</ArrivalDateTime>
</xsl:template>
回答by Phillip Koerner
I realize this thread is old and there's probably no need to add another answer.
我意识到这个线程很旧,可能没有必要添加另一个答案。
However, I can't help but nitpick that the previous answers, while technically correct for this given XML fragment, wouldn't work if this XML fragment were part of a larger document. In other words, these solutions match on the root node "/" and therefore will ONLY work when ArrivalDateTime is the root node of the document. Realistically, this will probably never be the case.
但是,我不禁挑剔了以前的答案,虽然在技术上对这个给定的 XML 片段是正确的,但如果这个 XML 片段是更大文档的一部分,就行不通了。换句话说,这些解决方案在根节点“/”上匹配,因此仅在 ArrivalDateTime 是文档的根节点时才有效。实际上,情况可能永远不会如此。
A recursive copy would be a more adaptable solution:
递归副本将是一个更具适应性的解决方案:
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="node()|@*|text()">
<xsl:copy>
<xsl:apply-templates select="node()|@*|text()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Date">
<dayOfMonth>
<xsl:value-of select="substring(., 1, 2)"/>
</dayOfMonth>
<month>
<xsl:value-of select="substring(., 3, 3)"/>
</month>
<year>
<xsl:value-of select="substring(., 6)"/>
</year>
</xsl:template>
</xsl:stylesheet>
回答by Mads Hansen
You have the right idea, but have things a little mixed up. It looks like you are expecting some pieces of the XSLT to be evaluated as it is streaming out "text".
你的想法是正确的,但事情有点混乱。看起来您希望 XSLT 的某些部分在流出“文本”时得到评估。
In your XSLT, you are constructing nodesthat will be serialized out as XML.
在您的 XSLT 中,您正在构建将作为 XML 序列化的节点。
This transform will produce the desired result.
此转换将产生所需的结果。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output indent="yes" />
<xsl:template match="/">
<ArrivalDateTime>
<dayOfMonth><xsl:value-of select="substring(/ArrivalDateTime/Date,1,2)"/></dayOfMonth>
<month><xsl:value-of select="substring(/ArrivalDateTime/Date,3,3)"/></month>
<year><xsl:value-of select="substring(/ArrivalDateTime/Date,6,4)"/></year>
</ArrivalDateTime>
</xsl:template>
</xsl:stylesheet>

