我是XSLT的新手。我的目的是基于字段从XML中删除元素,如果它高于某个阈值,我将作为参数获取它。
我的XML如下所示:
<tns:PM objectClass="MyNode" objectName="" className="com.project.converter.PMFamilyConverter" interfaceName="ComponentPM"
xmlns:tns="http://www.myproject/SS/PMSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.myProject.com/SS/PM.xsd">
<tns:family desc="family0" id="f0" eventNumber="000000">
<tns:performanceIndicator desc="Description 1" id="Success" eventNumber="000001" />
<tns:performanceIndicator desc="Description 2" id="Error" eventNumber="000002" />
</tns:family>
<tns:family desc="family1" id="f1" eventNumber="010000">
<tns:performanceIndicator desc="Description 1" id="Success" eventNumber="010001" />
<tns:performanceIndicator desc="Description 2" id="Name Error" eventNumber="010002" />
<tns:performanceIndicator desc="Description 3" id="Server Not Found Error" eventNumber="010003" />
</tns:family>
<tns:family desc="family2" id="f2" eventNumber="020000">
<tns:performanceIndicator desc="Description 1" id="Success" eventNumber="020001" />
<tns:performanceIndicator desc="Description 2" id="Format Error" eventNumber="020002" />
<tns:performanceIndicator desc="Description 3" id="Logic Error" eventNumber="020003" />
<tns:performanceIndicator desc="Description 4" id="Success with warning message" eventNumber="020004" />
</tns:family>
<tns:family desc="family3" id="f3" eventNumber="030000">
<tns:performanceIndicator desc="Description 1" id="Success" eventNumber="030001" />
<tns:performanceIndicator desc="Description 2" id="Error" eventNumber="030002" />
</tns:family>
</tns:PM>
根据网上提供的一些样本,我写的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" version="1.0" encoding="UTF-8" standalone="no" indent="yes"/>
<xsl:param name="maxEventNum"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="/">
<xsl:apply-templates select="/*[contains(local-name(),'PM')]/*[contains(local-name(),'family')]/@eventNumber"/>
<xsl:if test="number(.) < $maxEventNum">
<xsl:copy-of select="/*[contains(local-name(),'PM')]/*[contains(local-name(),'family')]"/>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
如果我将maxEventNumber作为020004
传递,我想要的输出如下所示。
<tns:PM objectClass="MyNode" objectName="" className="com.project.converter.PMFamilyConverter" interfaceName="ComponentPM"
xmlns:tns="http://www.myproject/SS/PMSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.myProject.com/SS/PM.xsd">
<tns:family desc="family0" id="f0" eventNumber="000000">
<tns:performanceIndicator desc="Description 1" id="Success" eventNumber="000001" />
<tns:performanceIndicator desc="Description 2" id="Error" eventNumber="000002" />
</tns:family>
<tns:family desc="family1" id="f1" eventNumber="010000">
<tns:performanceIndicator desc="Description 1" id="Success" eventNumber="010001" />
<tns:performanceIndicator desc="Description 2" id="Name Error" eventNumber="010002" />
<tns:performanceIndicator desc="Description 3" id="Server Not Found Error" eventNumber="010003" />
</tns:family>
</tns:PM>
您也可以告诉apply-template
何时以及如何使用match
如果在apply-template
内使用match
则与@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
if (activity instanceof CustomListener) {
listener = (CustomListener)activity;
} else {
throw new ClassCastException("Parent activity must implement CustomListener");
}
}
相关。
答案 0 :(得分:1)
第一件事:您应该在您的输入XML中使用命名空间/ s,而不是使用像*[contains(local-name(),'...')]
这样的尴尬表达式来围绕它们跳舞。
现在,排除特定节点的最简单方法是从身份转换模板开始(如您所示)将所有节点复制为规则,然后添加与您想要的节点匹配的空模板排除作为例外。
但是,当您要排除的节点由参数确定时,这不起作用,因为模板的匹配模式不能包含对变量的引用。在这种情况下,您可以使模板的内容成为条件:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:tns="http://www.myproject/SS/PMSchema">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="maxEventNum" select="020004"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="tns:family">
<xsl:if test="@eventNumber < $maxEventNum">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
注意 :( 1)添加的xmlns:tns="http://www.myproject/SS/PMSchema"
命名空间声明和tns:
前缀的使用,以及(2)<
运算符的转义为<
。
另一种解决方案是确保模板仅应用于符合条件的tns:family
个节点:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:tns="http://www.myproject/SS/PMSchema">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="maxEventNum" select="020004"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/tns:PM">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates select="tns:family[@eventNumber < $maxEventNum]"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
答案 1 :(得分:1)
假设 - 基于预期的输出XML-您想要评估eventNumber
及其后代元素fe family
元素中的performanceIndicator
属性,您可以尝试以下XSLT:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:tns="http://www.myproject/SS/PMSchema">
<xsl:output method="xml" version="1.0" encoding="UTF-8" standalone="no" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="maxEventNum" select="020004"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="/tns:PM/tns:family">
<xsl:if test="count(.//@eventNumber[number(.) >= $maxEventNum]) = 0">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
family
个元素 - ;更具体的模板会覆盖更一般的模板。此模板测试当前上下文eventNumber
中的任何family
属性是否值等于或高于而非隐式表示当自身的阈值为eventNumber=020004
时,应从输出中删除020004
。如果没有此类eventNumber
属性(count(...)=0
),请将当前family
元素复制到输出中,否则不要复制/不执行任何操作。