使用XSLT 1.0,我需要查找to
和from
类别中是否存在重复节点或单个节点。
我发现这种节点的XSL比较非常相似,但也无法使其工作。
XML:
<acl>
<enabled>true</enabled>
<from>
<rule>
<name>1.1.1.1</name>
<pattern>1.1.1.1</pattern>
<allow/>
<log>true</log>
<alarm>0</alarm>
</rule>
<rule>
<name>1.1.1.3</name>
<pattern>1.1.1.3</pattern>
<allow/>
<log>false</log>
<alarm>0</alarm>
</rule>
<rule>
<name>1.1.1.4</name>
<pattern>1.1.1.4</pattern>
<deny/>
<log>true</log>
<alarm>0</alarm>
</rule>
<fallthrough>
<allow/>
<log>true</log>
<alarm>0</alarm>
</fallthrough>
</from>
<to>
<rule>
<name>1.1.1.2</name>
<pattern>1.1.1.2</pattern>
<allow/>
<log>true</log>
<alarm>0</alarm>
</rule>
<rule>
<name>1.1.1.3</name>
<pattern>1.1.1.3</pattern>
<allow/>
<log>false</log>
<alarm>0</alarm>
</rule>
<rule>
<name>1.1.1.4</name>
<pattern>1.1.1.4</pattern>
<deny/>
<log>true</log>
<alarm>0</alarm>
</rule>
<fallthrough>
<allow/>
<log>false</log>
<alarm>0</alarm>
</fallthrough>
</to>
</acl>
期望结果:
1.1.1.1将显示"from"(来自from
部分)
1.1.1.3将显示"both"(它存在于from
和to
部分)
1.1.1.2将显示"to"(来自to
部分)
我已经想好了如何将1.1.1.4写为"none",因为只要它显示<deny/>
,我就可以将其打印为"none"。但我不知道如何测试它们是存在于XPath的两个部分中,还是仅存在于一个部分中。
我已经开始做但没有工作。
XSL:(不工作)
<xsl:apply-templates select="acl">
<xsl:if test="from/rule/name = to/rule/name">
<xsl:text>both</xsl:text>
</xsl:if>
</xsl:apply-templates>
我意识到,如果两个节点完全相同,还有其他帖子会找到副本xml并将其匹配并删除。但我并没有试图删除它,而是试图报告是否存在重复的节点以及它们来自哪里。
这样的东西适合你吗?
<?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" version="1.0" encoding="utf-8" indent="yes"/>
<xsl:key name="from" match="from/rule" use="name" />
<xsl:key name="to" match="to/rule" use="name" />
<xsl:template match="/acl">
<result>
<group desc="from">
<xsl:apply-templates select="from/rule[not(key('to', name))]"/>
</group>
<group desc="to">
<xsl:apply-templates select="to/rule[not(key('from', name))]"/>
</group>
<group desc="both">
<xsl:apply-templates select="from/rule[key('to', name)]"/>
</group>
</result>
</xsl:template>
<xsl:template match="rule">
<xsl:copy-of select="." />
</xsl:template>
</xsl:stylesheet>
结果:
<?xml version="1.0" encoding="utf-8"?>
<result>
<group desc="from">
<rule>
<name>1.1.1.1</name>
<pattern>1.1.1.1</pattern>
<allow/>
<log>true</log>
<alarm>0</alarm>
</rule>
</group>
<group desc="to">
<rule>
<name>1.1.1.2</name>
<pattern>1.1.1.2</pattern>
<allow/>
<log>true</log>
<alarm>0</alarm>
</rule>
</group>
<group desc="both">
<rule>
<name>1.1.1.3</name>
<pattern>1.1.1.3</pattern>
<allow/>
<log>false</log>
<alarm>0</alarm>
</rule>
<rule>
<name>1.1.1.4</name>
<pattern>1.1.1.4</pattern>
<deny/>
<log>true</log>
<alarm>0</alarm>
</rule>
</group>
</result>
编辑
本质上是一样的,HTML输出:
<?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" version="1.0" encoding="utf-8" indent="yes"/>
<xsl:key name="from" match="from/rule" use="name" />
<xsl:key name="to" match="to/rule" use="name" />
<xsl:template match="/acl">
<h3>From</h3>
<xsl:apply-templates select="from/rule[not(key('to', name))]"/>
<h3>To</h3>
<xsl:apply-templates select="to/rule[not(key('from', name))]"/>
<h3>Both</h3>
<xsl:apply-templates select="from/rule[key('to', name)]"/>
</xsl:template>
<xsl:template match="rule">
<p><xsl:value-of select="name" /></p>
</xsl:template>
</xsl:stylesheet>
结果:
<h3>From</h3>
<p>1.1.1.1</p>
<h3>To</h3>
<p>1.1.1.2</p>
<h3>Both</h3>
<p>1.1.1.3</p>
<p>1.1.1.4</p>
呈现为:
来自
1.1.1.1
到
1.1.1.2
两者
1.1.1.3
1.1.1.4
这里有另一个选项,可以按原样复制文档,并且只在原地向规则添加一个属性:
<?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" version="1.0" encoding="utf-8" indent="yes"/>
<xsl:key name="from" match="from/rule" use="name" />
<xsl:key name="to" match="to/rule" use="name" />
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="rule">
<xsl:copy>
<xsl:attribute name="group">
<xsl:choose>
<xsl:when test="parent::from and not(key('to', name))">
<xsl:text>from</xsl:text>
</xsl:when>
<xsl:when test="parent::to and not(key('from', name))">
<xsl:text>to</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>both</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
结果:
<?xml version="1.0" encoding="utf-8"?>
<acl>
<enabled>true</enabled>
<from>
<rule group="from">
<name>1.1.1.1</name>
<pattern>1.1.1.1</pattern>
<allow/>
<log>true</log>
<alarm>0</alarm>
</rule>
<rule group="both">
<name>1.1.1.3</name>
<pattern>1.1.1.3</pattern>
<allow/>
<log>false</log>
<alarm>0</alarm>
</rule>
<rule group="both">
<name>1.1.1.4</name>
<pattern>1.1.1.4</pattern>
<deny/>
<log>true</log>
<alarm>0</alarm>
</rule>
<fallthrough>
<allow/>
<log>true</log>
<alarm>0</alarm>
</fallthrough>
</from>
<to>
<rule group="to">
<name>1.1.1.2</name>
<pattern>1.1.1.2</pattern>
<allow/>
<log>true</log>
<alarm>0</alarm>
</rule>
<rule group="both">
<name>1.1.1.3</name>
<pattern>1.1.1.3</pattern>
<allow/>
<log>false</log>
<alarm>0</alarm>
</rule>
<rule group="both">
<name>1.1.1.4</name>
<pattern>1.1.1.4</pattern>
<deny/>
<log>true</log>
<alarm>0</alarm>
</rule>
<fallthrough>
<allow/>
<log>false</log>
<alarm>0</alarm>
</fallthrough>
</to>
</acl>