我的输入XML:
<Book>
<Chapter>
<Pages value="20" />
<Note1Code value="1" />
<Note1Description value="This is just for reference" />
<Note1Level value="Avg" />
<Note2Code value="2" />
<Note2Description value="This is high important note" />
<Note2Level value="Imp" />
</Chapter>
</Book>
我想转变为:
<Book>
<Chapter>
<Pages value="20" />
<Note>
<Code>1</Code>
<Description>This is just for reference</Description>
<Level>Avg</Level>
</Note
<Note>
<Code>2</Code>
<Description>This is high important note</Description>
<Level>Imp</Level>
</Note
</Chapter>
</Book>
这是我的XSLT:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[substring(name(), 1, 4) = 'Note' and substring(name(),6) = 'Code']">
<xsl:variable name="pdIdx" select="substring(name(), 5, 1)"/>
<xsl:variable name="pdNode" select="concat('Note',$pdIdx,'Description/@value')"/>
<xsl:variable name="pd" select="$pdNode"/>
<Code>
<xsl:value-of select="@value"/>
</Code>
<Description>
<xsl:value-of select="$pdNode"/>
</Description>
</xsl:template>
</xsl:stylesheet>
我正在尝试动态创建节点名称,然后尝试获取select属性中的值。但是,它不起作用。输出为:description标记采用节点名称而不是其值
<Book>
<Chapter>
<Pages value="20"/>
<Code>1</Code>
<Description>Note1Description/@value</Description>
<Node1Description value="This is just for reference"/>
<Note1Level value="Avg"/>
<Code>2</Code>
<Description>Note2Description/@value</Description>
<Node2Description value="This is high important note"/>
<Note2Level value="Imp"/>
</Chapter>
</Book>
答案 0 :(得分:2)
这看起来有些混乱,但我相信会这样做:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="elements" match="*" use="name()"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[starts-with(name(),'Note')
and
substring(name(),string-length(name())-3) = 'Code'
and
number(substring-before(substring-after(name(),'Note'),'Code'))]">
<xsl:variable name="Num" select="number(substring-before(substring-after(name(),'Note'),'Code'))"/>
<Note>
<Code><xsl:value-of select="key('elements', concat('Note',$Num,'Code'))/@value"/></Code>
<Description><xsl:value-of select="key('elements', concat('Note',$Num,'Description'))/@value"/></Description>
<Level><xsl:value-of select="key('elements', concat('Note',$Num,'Level'))/@value"/></Level>
</Note>
</xsl:template>
<xsl:template match="*[starts-with(name(),'Note')
and
((substring(name(),string-length(name())-10) = 'Description'
and
number(substring-before(substring-after(name(),'Note'),'Description')))
or (substring(name(),string-length(name())-4) = 'Level'
and
number(substring-before(substring-after(name(),'Note'),'Level'))))
]"/>
</xsl:stylesheet>
答案 1 :(得分:1)
我在您的代码中做了很少的更改
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[contains(name(), 'Note') and contains(name(), 'Code')]">
<xsl:variable name="pdIdx" select="translate(name(), 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz', '')"/>
<xsl:variable name="pdNode" select="following-sibling::*[contains(name(), concat('Note',$pdIdx,'Description'))]/@value"/>
<xsl:variable name="pdLevel" select="following-sibling::*[contains(name(), concat('Note',$pdIdx,'Level'))]/@value"/>
<xsl:variable name="pd" select="$pdNode"/>
<Note>
<Code>
<xsl:value-of select="@value"/>
</Code>
<Description>
<xsl:value-of select="$pdNode"/>
</Description>
<Level>
<xsl:value-of select="$pdLevel"/>
</Level>
</Note>
</xsl:template>
<xsl:template match="*[contains(name(), 'Description')]"/>
<xsl:template match="*[contains(name(), 'Level')]"/>
</xsl:stylesheet>
答案 2 :(得分:1)
这不可能是简单的:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[starts-with(name(), 'Note') and contains(name(), 'Code')]" priority="1">
<Note>
<Code>
<xsl:value-of select="@value"/>
</Code>
<Description>
<xsl:value-of select="following-sibling::*[1]/@value"/>
</Description>
<Level>
<xsl:value-of select="following-sibling::*[2]/@value"/>
</Level>
</Note>
</xsl:template>
<xsl:template match="*[starts-with(name(), 'Note')]"/>
</xsl:stylesheet>
此是,假设源文档中没有其他名称以“Note”开头的元素。