我想基于几件事增加元素中的值。首先,我想检查元素值的出现,然后在节点中出现相同ID的任何地方更改另一个元素值。
这是xml文件的外观示例:
<?xml version="1.0" encoding="UTF-8" ?>
<XMLLines>
<XMLLine>
<ID>"100"</ID>
<Type>"STEEL"</Type>
<Value>"1"</Value>
<ARG1>""</ARG1>
<ARG2>""</ARG2>
<ARG3>""</ARG3>
</XMLLine>
<XMLLine>
<ID>"100"</ID>
<Type>"STEEL"</Type>
<Value>"1"</Value>
<ARG1>""</ARG1>
<ARG2>""</ARG2>
<ARG3>""</ARG3>
</XMLLine>
<XMLLine>
<ID>"103"</ID>
<Type>"STEEL"</Type>
<Value>"1"</Value>
<ARG1>""</ARG1>
<ARG2>""</ARG2>
<ARG3>""</ARG3>
</XMLLine>
<XMLLine>
<ID>"103"</ID>
<Type>"STEEL"</Type>
<Value>"1"</Value>
<ARG1>""</ARG1>
<ARG2>""</ARG2>
<ARG3>""</ARG3>
</XMLLine>
<XMLLine>
<ID>"143"</ID>
<Type>"IRON"</Type>
<Value>"1"</Value>
<ARG1>""</ARG1>
<ARG2>""</ARG2>
<ARG3>""</ARG3>
</XMLLine>
<XMLLine>
<ID>"143"</ID>
<Type>"IRON"</Type>
<Value>"1"</Value>
<ARG1>""</ARG1>
<ARG2>""</ARG2>
<ARG3>""</ARG3>
</XMLLine>
<XMLLine>
<ID>"187"</ID>
<Type>"STEEL"</Type>
<Value>"1"</Value>
<ARG1>""</ARG1>
<ARG2>""</ARG2>
<ARG3>""</ARG3>
</XMLLine>
<XMLLine>
<ID>"187"</ID>
<Type>"STEEL"</Type>
<Value>"1"</Value>
<ARG1>""</ARG1>
<ARG2>""</ARG2>
<ARG3>""</ARG3>
</XMLLine>
</XMLLines>
这是xsl文件:
<?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="*">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:key name="TEST1" match="XMLLine[contains(./Type,'STEEL') and (./Value = document('Values.xml')/Values/Value)]" use="ID"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="ARG1[key('TEST1', ../ID)]">
<xsl:copy>
<xsl:value-of select="concat('STATUS = ', count(../preceding-sibling::XMLLine[key('TEST1', ID)]) + 1)"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
这是包含值的xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<Values>
<Value>"1"</Value>
<Value>"2"</Value>
<Value>"3"</Value>
<Value>"4"</Value>
<Value>"5"</Value>
<Value>"6"</Value>
<Value>"7"</Value>
<Value>"8"</Value>
</Values>
现在,输出看起来像:
<?xml version="1.0"?>
<XMLLines>
<XMLLine>
<ID>"100"</ID>
<Type>"STEEL"</Type>
<Value>"1"</Value>
<ARG1>STATUS = 1</ARG1>
<ARG2>""</ARG2>
<ARG3>""</ARG3>
</XMLLine>
<XMLLine>
<ID>"100"</ID>
<Type>"STEEL"</Type>
<Value>"1"</Value>
<ARG1>STATUS = 2</ARG1>
<ARG2>""</ARG2>
<ARG3>""</ARG3>
</XMLLine>
<XMLLine>
<ID>"103"</ID>
<Type>"STEEL"</Type>
<Value>"1"</Value>
<ARG1>STATUS = 3</ARG1>
<ARG2>""</ARG2>
<ARG3>""</ARG3>
</XMLLine>
<XMLLine>
<ID>"103"</ID>
<Type>"STEEL"</Type>
<Value>"1"</Value>
<ARG1>STATUS = 4</ARG1>
<ARG2>""</ARG2>
<ARG3>""</ARG3>
</XMLLine>
<XMLLine>
<ID>"143"</ID>
<Type>"IRON"</Type>
<Value>"1"</Value>
<ARG1>""</ARG1>
<ARG2>""</ARG2>
<ARG3>""</ARG3>
</XMLLine>
<XMLLine>
<ID>"143"</ID>
<Type>"IRON"</Type>
<Value>"1"</Value>
<ARG1>""</ARG1>
<ARG2>""</ARG2>
<ARG3>""</ARG3>
</XMLLine>
<XMLLine>
<ID>"187"</ID>
<Type>"STEEL"</Type>
<Value>"1"</Value>
<ARG1>STATUS = 5</ARG1>
<ARG2>""</ARG2>
<ARG3>""</ARG3>
</XMLLine>
<XMLLine>
<ID>"187"</ID>
<Type>"STEEL"</Type>
<Value>"1"</Value>
<ARG1>STATUS = 6</ARG1>
<ARG2>""</ARG2>
<ARG3>""</ARG3>
</XMLLine>
</XMLLines>
但实际上我需要它每次只增加一次,而不是像上面的输出那样每次增加。所以基本上我想得到以下输出:
<?xml version="1.0"?>
<XMLLines>
<XMLLine>
<ID>"100"</ID>
<Type>"STEEL"</Type>
<Value>"1"</Value>
<ARG1>STATUS = 1</ARG1>
<ARG2>""</ARG2>
<ARG3>""</ARG3>
</XMLLine>
<XMLLine>
<ID>"100"</ID>
<Type>"STEEL"</Type>
<Value>"1"</Value>
<ARG1>STATUS = 1</ARG1>
<ARG2>""</ARG2>
<ARG3>""</ARG3>
</XMLLine>
<XMLLine>
<ID>"103"</ID>
<Type>"STEEL"</Type>
<Value>"1"</Value>
<ARG1>STATUS = 2</ARG1>
<ARG2>""</ARG2>
<ARG3>""</ARG3>
</XMLLine>
<XMLLine>
<ID>"103"</ID>
<Type>"STEEL"</Type>
<Value>"1"</Value>
<ARG1>STATUS = 2</ARG1>
<ARG2>""</ARG2>
<ARG3>""</ARG3>
</XMLLine>
<XMLLine>
<ID>"143"</ID>
<Type>"IRON"</Type>
<Value>"1"</Value>
<ARG1>""</ARG1>
<ARG2>""</ARG2>
<ARG3>""</ARG3>
</XMLLine>
<XMLLine>
<ID>"143"</ID>
<Type>"IRON"</Type>
<Value>"1"</Value>
<ARG1>""</ARG1>
<ARG2>""</ARG2>
<ARG3>""</ARG3>
</XMLLine>
<XMLLine>
<ID>"187"</ID>
<Type>"STEEL"</Type>
<Value>"1"</Value>
<ARG1>STATUS = 3</ARG1>
<ARG2>""</ARG2>
<ARG3>""</ARG3>
</XMLLine>
<XMLLine>
<ID>"187"</ID>
<Type>"STEEL"</Type>
<Value>"1"</Value>
<ARG1>STATUS = 3</ARG1>
<ARG2>""</ARG2>
<ARG3>""</ARG3>
</XMLLine>
</XMLLines>
有关如何使用XSLT 1.0实现此目的的任何想法?谢谢!
答案 0 :(得分: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:key name="k" match="XMLLine" use="concat(ID, '|', type)"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="ARG1[contains(../Type,'STEEL')]">
<xsl:copy>
<xsl:text>STATUS=</xsl:text>
<xsl:value-of select="count((..|../preceding-sibling::XMLLine)[contains(Type,'STEEL')][count(. | key('k', concat(ID, '|', type))[1]) = 1])" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
应用于以下测试输入:
<XMLLines>
<XMLLine>
<ID>"100"</ID>
<Type>"STEEL"</Type>
<ARG1>""</ARG1>
</XMLLine>
<XMLLine>
<ID>"100"</ID>
<Type>"STEEL"</Type>
<ARG1>""</ARG1>
</XMLLine>
<XMLLine>
<ID>"100"</ID>
<Type>"STEEL"</Type>
<ARG1>""</ARG1>
</XMLLine>
<XMLLine>
<ID>"103"</ID>
<Type>"STEEL"</Type>
<ARG1>""</ARG1>
</XMLLine>
<XMLLine>
<ID>"103"</ID>
<Type>"STEEL"</Type>
<ARG1>""</ARG1>
</XMLLine>
<XMLLine>
<ID>"143"</ID>
<Type>"IRON"</Type>
<ARG1>""</ARG1>
</XMLLine>
<XMLLine>
<ID>"143"</ID>
<Type>"IRON"</Type>
<ARG1>""</ARG1>
</XMLLine>
<XMLLine>
<ID>"187"</ID>
<Type>"STEEL"</Type>
<ARG1>""</ARG1>
</XMLLine>
<XMLLine>
<ID>"187"</ID>
<Type>"STEEL"</Type>
<ARG1>""</ARG1>
</XMLLine>
</XMLLines>
结果是:
<?xml version="1.0" encoding="UTF-8"?>
<XMLLines>
<XMLLine>
<ID>"100"</ID>
<Type>"STEEL"</Type>
<ARG1>STATUS=1</ARG1>
</XMLLine>
<XMLLine>
<ID>"100"</ID>
<Type>"STEEL"</Type>
<ARG1>STATUS=1</ARG1>
</XMLLine>
<XMLLine>
<ID>"100"</ID>
<Type>"STEEL"</Type>
<ARG1>STATUS=1</ARG1>
</XMLLine>
<XMLLine>
<ID>"103"</ID>
<Type>"STEEL"</Type>
<ARG1>STATUS=2</ARG1>
</XMLLine>
<XMLLine>
<ID>"103"</ID>
<Type>"STEEL"</Type>
<ARG1>STATUS=2</ARG1>
</XMLLine>
<XMLLine>
<ID>"143"</ID>
<Type>"IRON"</Type>
<ARG1>""</ARG1>
</XMLLine>
<XMLLine>
<ID>"143"</ID>
<Type>"IRON"</Type>
<ARG1>""</ARG1>
</XMLLine>
<XMLLine>
<ID>"187"</ID>
<Type>"STEEL"</Type>
<ARG1>STATUS=3</ARG1>
</XMLLine>
<XMLLine>
<ID>"187"</ID>
<Type>"STEEL"</Type>
<ARG1>STATUS=3</ARG1>
</XMLLine>
</XMLLines>
我不确定为什么需要一份列出一些递增数字的单独文件。
虽然上述内容已经比您的尝试更简单,但通过为每个组分配唯一ID,而不是增加数量(这需要计算以前的组),可以使其更简单。例如:
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:key name="k" match="XMLLine" use="concat(ID, '|', type)"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="ARG1[contains(../Type,'STEEL')]">
<xsl:copy>
<xsl:text>STATUS=</xsl:text>
<xsl:value-of select="generate-id(key('k', concat(../ID, '|', ../type))[1])" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
会返回类似的内容:
<?xml version="1.0" encoding="UTF-8"?>
<XMLLines>
<XMLLine>
<ID>"100"</ID>
<Type>"STEEL"</Type>
<ARG1>STATUS=d0e2</ARG1>
</XMLLine>
<XMLLine>
<ID>"100"</ID>
<Type>"STEEL"</Type>
<ARG1>STATUS=d0e2</ARG1>
</XMLLine>
<XMLLine>
<ID>"100"</ID>
<Type>"STEEL"</Type>
<ARG1>STATUS=d0e2</ARG1>
</XMLLine>
<XMLLine>
<ID>"103"</ID>
<Type>"STEEL"</Type>
<ARG1>STATUS=d0e23</ARG1>
</XMLLine>
<XMLLine>
<ID>"103"</ID>
<Type>"STEEL"</Type>
<ARG1>STATUS=d0e23</ARG1>
</XMLLine>
<XMLLine>
<ID>"143"</ID>
<Type>"IRON"</Type>
<ARG1>""</ARG1>
</XMLLine>
<XMLLine>
<ID>"143"</ID>
<Type>"IRON"</Type>
<ARG1>""</ARG1>
</XMLLine>
<XMLLine>
<ID>"187"</ID>
<Type>"STEEL"</Type>
<ARG1>STATUS=d0e51</ARG1>
</XMLLine>
<XMLLine>
<ID>"187"</ID>
<Type>"STEEL"</Type>
<ARG1>STATUS=d0e51</ARG1>
</XMLLine>
</XMLLines>
答案 1 :(得分:0)
实际上,建议的答案对于获得预期的解决方案并没有多大帮助,但我已经找到了解决方法以实现所需的转换。当然,这仅适用于每个匹配事件总共有两个相同ID的当前情况。
<?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="*">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:key name="TEST1" match="XMLLine[contains(./Type,'STEEL') and (./Value = document('Values.xml')/Values/Value)]" use="ID"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="ARG1[key('TEST1', ../ID)]">
<xsl:copy>
<xsl:value-of select="concat('STATUS = ', round((count(../preceding-sibling::XMLLine[key('TEST1', ID)]) + 1) div 2))"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>