如何从节点复制某些属性。我想从节点“Extn”中仅复制“Srno”,“RollNo”,“right”。
<Main>
<SubMainLevel1 material="12" feature="range">
<SubMainLevel2 arg1="abc" arg2="123">
<Item name="hello" desc="one" />
<Detail long="high" short="wide" />
<Extn Srno="12" RollNo="12" weight="12" folds="2" right="Y" left="N" top="T" bottom="V" />
</SubMainLevel2>
<SubMainLevel2 arg1="cyz" arg2="123">
<Item name="hello2" desc="two" />
<Detail long="short" short="wide" />
<Extn Srno="" RollNo="" weight="" folds="1" right="Y" left="N" top="T" bottom="V" />
</SubMainLevel2>
</SubMainLevel1>
</Main>
我使用的Xsl如下:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:strip-space elements="*" />
<xsl:template match="/">
<Job>
<xsl:copy-of select="Main/SubMainLevel1/@*[name()='material']" />
<Lines>
<xsl:for-each select="/Main/SubMainLevel1/SubMainLevel2">
<xsl:if test="@arg2 = '123'">
<Line>
<xsl:copy-of select="@*" />
<xsl:copy-of select="node()[name() = 'Item']" />
<xsl:copy-of select="node()[name() = 'Detail']" />
<xsl:copy-of select="node()[name() = 'Extn']" />
</Line>
</xsl:if>
</xsl:for-each>
</Lines>
</Job>
</xsl:template>
</xsl:stylesheet>
这里我怎么能用上面提到的值限制节点“Extn”。
预期输出
<?xml version="1.0" encoding="UTF-8"?>
<Job material="12">
<Lines>
<Line arg1="abc" arg2="123">
<Item name="hello" desc="one" />
<Detail long="high" short="wide" />
<Extn Srno="12" RollNo="12" right="Y"/>
</Line>
<Line arg1="cyz" arg2="123">
<Item name="hello2" desc="two" />
<Detail long="short" short="wide" />
<Extn Srno="" RollNo="" right="Y"/>
</Line>
</Lines>
</Job>
不同
答案 0 :(得分:3)
我认为您可以使用此处的identity template
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
这意味着不要写这个....
<Line>
<xsl:copy-of select="@*" />
<xsl:copy-of select="node()[name() = 'Item']" />
<xsl:copy-of select="node()[name() = 'Detail']" />
<xsl:copy-of select="node()[name() = 'Extn']" />
</Line>
你可以写这个
<Line>
<xsl:apply-templates select="@*|node()"/>
</Line>
然后,当您可以选择所需的属性时,您只需要一个匹配 Extn 的模板
<xsl:template match="Extn">
<xsl:copy>
<xsl:apply-templates select="@Srno|@RollNo|@right|node()"/>
</xsl:copy>
</xsl:template>
试试这个XSLT
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:strip-space elements="*" />
<xsl:output method="xml" indent="yes" />
<xsl:template match="Main">
<Job>
<xsl:copy-of select="SubMainLevel1/@*[name()='material']" />
<Lines>
<xsl:apply-templates select="SubMainLevel1/SubMainLevel2[@arg2 = '123']" />
</Lines>
</Job>
</xsl:template>
<xsl:template match="SubMainLevel2">
<Line>
<xsl:apply-templates select="@*|node()"/>
</Line>
</xsl:template>
<xsl:template match="Extn">
<xsl:copy>
<xsl:apply-templates select="@Srno|@RollNo|@right|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
注意我在这里使用 SubMainLevel2 上的模板匹配,而不是 xsl:for-each ,还要注意不需要 xsl: if ,因为条件可以作为select表达式的一部分。
答案 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="/">
<Job material="{Main/SubMainLevel1/@material}">
<Lines>
<xsl:for-each select="Main/SubMainLevel1/SubMainLevel2[@arg2=123]">
<Line>
<xsl:copy-of select="@* | Item | Detail" />
<Extn Srno="{Extn/@Srno}" RollNo="{Extn/@RollNo}" right="{Extn/@right}" />
</Line>
</xsl:for-each>
</Lines>
</Job>
</xsl:template>
</xsl:stylesheet>