我有一个非常扁平的XML文件,我想根据某种输入列表更改一些属性。我无法解决的棘手问题是我不仅要在一个节点上更改属性,还要在引用找到的节点的兄弟节点上更改属性。
我有以下XML文件:
<?xml version="1.0" encoding="utf-8"?>
<Root>
<SubItem id="id21" cls="classA" name="FirstSub" master="#id30"/>
<SubItem id="id22" cls="classA" name="SecondSub" master="#id31"/>
<SubItem id="id23" cls="classA" name="ThirdSub" master="#id32"/>
<SubItem id="id24" cls="classA" name="FourthSub" master="#id33"/>
<SubItem id="id25" cls="classA" name="FifthSub" master="#id34"/>
<Item id="id30" cls="classA" name="First"/>
<Item id="id31" cls="classA" name="Second"/>
<Item id="id32" cls="classA" name="Third"/>
<Item id="id33" cls="classA" name="Fourth"/>
<Item id="id34" cls="classA" name="Fifth" />
</Root>
以下附加输入文件列出了我想要更改name
属性值的元素的cls
值:
<input>
<ToClassB>
<Name>Second</Name>
<Name>Third</Name>
</ToClassB>
</input>
以下XSLT,适用于name
值与其他输入列表中的值相匹配的元素:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:plm="http://www.plmxml.org/Schemas/PLMXMLSchema" exclude-result-prefixes="xs"
version="2.0">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="no"/>
<xsl:variable name="inputs" select="document('file:/C:/Temp//demoInput.xml')"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/Root/Item/@name[. = $inputs/input/ToClassB/Name/text()]">
<xsl:variable name="elemName" select="../@id"/>
<xsl:copy>
<xsl:copy-of select="../@name"/>
</xsl:copy>
<xsl:attribute name="cls">
<xsl:value-of select="'classB'" />
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
我的预期结果:
<?xml version="1.0" encoding="UTF-8"?>
<Root>
<SubItem id="id21" cls="classA" name="FirstSub" master="#id30"/>
<SubItem id="id22" cls="ClassB" name="SecondSub" master="#id31"/>
<SubItem id="id23" cls="ClassB" name="ThirdSub" master="#id32"/>
<SubItem id="id24" cls="classA" name="FourthSub" master="#id33"/>
<SubItem id="id25" cls="classA" name="FifthSub" master="#id34"/>
<Item id="id30" cls="classA" name="First"/>
<Item id="id31" cls="ClassB" name="Second"/>
<Item id="id32" cls="ClassB" name="Third"/>
<Item id="id33" cls="classA" name="Fourth"/>
<Item id="id34" cls="classA" name="Fifth"/>
</Root>
name
值为"Second"
或"Third"
的商品代码匹配,其cls
属性值更改为ClassB
,以及{ {1}}相关cls
元素的属性值(SubItem
元素上的主属性引用ID属性)。
这对XSLT是否可行?或者我是否需要使用某些编程?
答案 0 :(得分:0)
您可以创建一个xsl:键,以引用Item
中的SubItem
。您可以使用单个模板,并使用id
或master
属性来访问密钥。
示例...
XSLT 2.0
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="itemsByID" match="Item" use="@id"/>
<xsl:variable name="inputs"
select="document('demoInput.xml')/input/ToClassB/Name"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Item|SubItem">
<xsl:variable name="refid"
select="if (@master) then substring-after(@master,'#') else @id"/>
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:attribute name="cls"
select="if (key('itemsByID',$refid)/@name = $inputs)
then 'ClassB' else @cls"/>
<xsl:apply-templates select="node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
<强>输出强>
<Root>
<SubItem id="id21" cls="classA" name="FirstSub" master="#id30"/>
<SubItem id="id22" cls="ClassB" name="SecondSub" master="#id31"/>
<SubItem id="id23" cls="ClassB" name="ThirdSub" master="#id32"/>
<SubItem id="id24" cls="classA" name="FourthSub" master="#id33"/>
<SubItem id="id25" cls="classA" name="FifthSub" master="#id34"/>
<Item id="id30" cls="classA" name="First"/>
<Item id="id31" cls="ClassB" name="Second"/>
<Item id="id32" cls="ClassB" name="Third"/>
<Item id="id33" cls="classA" name="Fourth"/>
<Item id="id34" cls="classA" name="Fifth"/>
</Root>