我需要使用XSLT将XML(1.0)转换为TXT以供人们阅读
并在【template match =“/”>】区域内进行
这是我的XML:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<?xml-stylesheet type="text/xsl" href="OutputFile.xslt"?>
<File>
<Header>
<A><![CDATA[Order]]></A>
<B><![CDATA[Add]]></B>
<C><![CDATA[BN]]></C>
<D><![CDATA[Comment]]></D>
<E><![CDATA[Base]]></E>
</Header>
<Data>
<row A="1" B="X" C="11.00000" D="" E="0"/>
<row A="2" B="X" C="5.00000" D="" E="0"/>
<row A="3" B="X" C="11.00000" D="" E="0"/>
</Data>
<Table>
<Bin Name ="A1" BinNum="1" BinDesc="Type_S" End=""/>
<Bin Name ="A4" BinNum="2" BinDesc="Type_AC3" End=""/>
<Bin Name ="A9" BinNum="3" BinDesc="Type_E5" End=""/>
<Bin Name ="A12" BinNum="4" BinDesc="Type_E5" End=""/>
<Bin Name ="A14" BinNum="5" BinDesc="Type_E5" End=""/>
<Bin Name ="A22" BinNum="6" BinDesc="Type_E5" End=""/>
<Bin Name ="A23" BinNum="7" BinDesc="Type_E6" End=""/>
<Bin Name ="A24" BinNum="8" BinDesc="Type_AF3C" End=""/>
<Bin Name ="A56" BinNum="9" BinDesc="Type_none" End=""/>
<Bin Name ="A57" BinNum="10" BinDesc="Type_defalt" End=""/>
<Bin Name ="A70" BinNum="11" BinDesc="Type_auto" End=""/>
<Bin Name ="A71" BinNum="0" BinDesc="Type_mau" End=""/>
</Table>
</File>
我需要搜索[BN]的Header,知道它位于C, 然后搜索attritube C的数据/行, 最后使用此值来比较Table中的BinNum并打印相应的类型
这是我的XSLT
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ms="urn:schemas-microsoft-com:xslt"
xmlns:fn="http://www.w3.org/2006/xpath-functions">
<xsl:output method="text" indent="yes"/>
<xsl:template match="/">
<xsl:text>What I want to print is the value of position 11,5,11</xsl:text>
<xsl:text> </xsl:text>
<xsl:value-of select="/File/Table/Bin[position()=11]/@*[position()=3]"/>
<xsl:text> </xsl:text>
<xsl:value-of select="/File/Table/Bin[position()=5]/@*[position()=3]"/>
<xsl:text> </xsl:text>
<xsl:value-of select="/File/Table/Bin[position()=11]/@*[position()=3]"/>
<xsl:text> </xsl:text>
<xsl:variable name="BN">
<xsl:choose>
<xsl:when test="count(/File/Header/*[text()='BN']) = 1">
<xsl:value-of select="count(/File/Header/*[text()='BN']/preceding-sibling::*) + 1"/>
</xsl:when>
</xsl:choose>
</xsl:variable>
<xsl:variable name="BN_location">
<xsl:for-each select="/File/Data/row">
<xsl:for-each select="@*">
<xsl:if test="position() =$BN">
<xsl:value-of select="number(.)"/>
</xsl:if>
</xsl:for-each>
</xsl:for-each>
</xsl:variable>
<xsl:text> </xsl:text>
<xsl:text>But so far I can only print the number 11,5,11 ~~so sad!</xsl:text>
<xsl:text> </xsl:text>
<xsl:for-each select="/File/Data/row">
<xsl:for-each select="@*">
<xsl:if test="position() =$BN">
<xsl:value-of select="number(.)"/>
<xsl:text>;</xsl:text>
</xsl:if>
</xsl:for-each>
<xsl:value-of select="/File/Table/Bin[position()=$BN_location]/@*[position()=2]"/>
<xsl:text> </xsl:text>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
输出是
What I want to print is the value of position 11,5,11
Type_auto
Type_E5
Type_auto
But so far I can only print the number 11,5,11 ~~so sad!
11;
5;
11;
任何帮助? THX!
答案 0 :(得分:1)
您可以按如下方式获得所需的输出。首先使用BN
函数在text()
中找到包含local-name()
值的节点。
<xsl:variable name="BNNode" select="local-name(/File/Header/*[text() = 'BN'])" />
使用此节点,循环遍历<row>
的属性,使属性名称与节点名称匹配。
<xsl:for-each select="/File/Data/row/@*[local-name() = $BNNode]">
循环遍历<Bin>
所有@BinNum
匹配从上述for-each
循环接收的属性值的所有内容。
<xsl:for-each select="/File/Table/Bin[@BinNum = number($attrVal)]">
选择并打印@BinDesc
。
完整的XSLT如下所示。
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:output method="text" indent="yes"/>
<xsl:strip-space elements="*" />
<xsl:variable name="BNNode" select="local-name(/File/Header/*[text() = 'BN'])" />
<xsl:template match="/">
<xsl:for-each select="/File/Data/row/@*[local-name() = $BNNode]">
<xsl:variable name="attrVal" select="." />
<xsl:for-each select="/File/Table/Bin[@BinNum = number($attrVal)]">
<xsl:value-of select="@BinDesc" />
<xsl:text> </xsl:text>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
输出
Type_auto
Type_E5
Type_auto
答案 1 :(得分:1)
这是(在我看来)使用键执行此操作的优雅方式:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" indent="yes" omit-xml-declaration="yes"/>
<xsl:key name="rowAttribsByName" match="Data/row/@*" use="name()"/>
<xsl:key name="binsByNum" match="Table/Bin" use="@BinNum"/>
<xsl:template match="/File">
<xsl:variable name="targetAttribName" select="name(Header/*[. = 'BN'])" />
<xsl:for-each select="key('rowAttribsByName', $targetAttribName)">
<xsl:value-of select="key('binsByNum', number())/@BinDesc"/>
<xsl:text>
</xsl:text>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
在样本输入上运行时,结果为:
Type_auto
Type_E5
Type_auto
答案 2 :(得分:0)
这是我使用嵌套for-each的解决方案。 我希望这会对你有所帮助。
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ms="urn:schemas-microsoft-com:xslt"
xmlns:fn="http://www.w3.org/2006/xpath-functions">
<xsl:output method="text" indent="yes"/>
<xsl:template match="/">
<xsl:variable name="BN_location" select="name(/File/Header/*[text()='BN'])"/>
<xsl:for-each select="/File/Data/row/@*[local-name()=$BN_location]">
<xsl:variable name="BN_attr" select="." />
<xsl:for-each select="/File/Table/Bin[@BinNum = round($BN_attr)]">
<xsl:value-of select="./@BinDesc"/>
<xsl:text>|</xsl:text>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>