XSLT 1.0 使用包含外部参数节点集
XSLT 1.0 Using Contains with External Parameter Node Set
我正在尝试将特定节点 (EN_PLAN_NAME) 中的文本与字符串列表进行比较,以便我可以仅输出包含与以下之一匹配的文本的节点那些字符串。我尝试使用这个类似问题的答案:
How to compare against multiple strings in xslt
输入XML
<EligibilityRecords xmlns="http://CDHC_Eligibility_LSDD">
<Eligibility_Detail_Record xmlns="">
<EN_PLAN_NAME>Health Savings Account</EN_PLAN_NAME>
<EN_MBRSHP_EFF_STRT_DT>01012017</EN_MBRSHP_EFF_STRT_DT>
</Eligibility_Detail_Record>
<Eligibility_Detail_Record xmlns="">
<EN_PLAN_NAME>zzHealth Reimbursement Arrangement</EN_PLAN_NAME>
<EN_MBRSHP_EFF_STRT_DT>01012017</EN_MBRSHP_EFF_STRT_DT>
</Eligibility_Detail_Record>
<Eligibility_Detail_Record xmlns="">
<EN_PLAN_NAME>Health Reimbursement Arrangement 233</EN_PLAN_NAME>
<EN_MBRSHP_EFF_STRT_DT>01012017</EN_MBRSHP_EFF_STRT_DT>
</Eligibility_Detail_Record>
<Eligibility_Detail_Record xmlns="">
<EN_PLAN_NAME>HRA</EN_PLAN_NAME>
<EN_MBRSHP_EFF_STRT_DT>01012017</EN_MBRSHP_EFF_STRT_DT>
</Eligibility_Detail_Record>
<Eligibility_Detail_Record xmlns="">
<EN_PLAN_NAME>BASE HRA</EN_PLAN_NAME>
<EN_MBRSHP_EFF_STRT_DT>01012017</EN_MBRSHP_EFF_STRT_DT>
</Eligibility_Detail_Record>
<Eligibility_Detail_Record xmlns="">
<EN_PLAN_NAME>FSA</EN_PLAN_NAME>
<EN_MBRSHP_EFF_STRT_DT>01012017</EN_MBRSHP_EFF_STRT_DT>
</Eligibility_Detail_Record>
</EligibilityRecords>
预期输出XML
<EligibilityRecords xmlns="CDHC_Eligibility_LSDD_Internal">
<Eligibility_Detail_Record xmlns="">
<EN_PLAN_NAME>zzHealth Reimbursement Arrangement</EN_PLAN_NAME>
<EN_MBRSHP_EFF_STRT_DT>01012017</EN_MBRSHP_EFF_STRT_DT>
</Eligibility_Detail_Record>
<Eligibility_Detail_Record xmlns="">
<EN_PLAN_NAME>Health Reimbursement Arrangement 233</EN_PLAN_NAME>
<EN_MBRSHP_EFF_STRT_DT>01012017</EN_MBRSHP_EFF_STRT_DT>
</Eligibility_Detail_Record>
<Eligibility_Detail_Record xmlns="">
<EN_PLAN_NAME>HRA</EN_PLAN_NAME>
<EN_MBRSHP_EFF_STRT_DT>01012017</EN_MBRSHP_EFF_STRT_DT>
</Eligibility_Detail_Record>
<Eligibility_Detail_Record xmlns="">
<EN_PLAN_NAME>BASE HRA</EN_PLAN_NAME>
<EN_MBRSHP_EFF_STRT_DT>01012017</EN_MBRSHP_EFF_STRT_DT>
</Eligibility_Detail_Record>
</EligibilityRecords>
XSLT
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:var="http://schemas.microsoft.com/BizTalk/2003/var"
exclude-result-prefixes="msxsl var s0 ns0" version="1.0"
xmlns:s0="CDHC_Eligibility_LSDD"
xmlns:ns0="CDHC_Eligibility_LSDD_Internal">
<xsl:output omit-xml-declaration="yes" method="xml" version="1.0" />
<xsl:param name="HRAPlanNames">
<PlanName>Health Reimbursement Arrangement</PlanName>
<PlanName>HRA</PlanName>
</xsl:param>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/*">
<ns0:EligibilityRecords>
<xsl:for-each select="Eligibility_Detail_Record">
<xsl:if test="contains(EN_PLAN_NAME,msxsl:node-set($HRAPlanNames)/*)">
<Eligibility_Detail_Record>
<xsl:copy-of select="EN_PLAN_NAME"/>
</Eligibility_Detail_Record>
</xsl:if>
</xsl:for-each>
</ns0:EligibilityRecords>
</xsl:template>
</xsl:stylesheet>
XSLT 输出任何 EN_PLAN_NAME 的文本包含 "Health Reimbursement Arrangement" 但不输出任何包含 "Health Reimbursement Arrangement" 的节点包含 "HRA"。我不确定我做错了什么。
注意:您可以从两个示例中取出 translate()
。在你编辑之前,我已经从你的问题中复制了输入内容。
我现在无法测试 msxsl,但试试这个:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:var="http://schemas.microsoft.com/BizTalk/2003/var"
exclude-result-prefixes="msxsl var s0 ns0" version="1.0"
xmlns:s0="CDHC_Eligibility_LSDD"
xmlns:ns0="CDHC_Eligibility_LSDD_Internal">
<xsl:output omit-xml-declaration="yes" method="xml" version="1.0" />
<xsl:param name="HRAPlanNames">
<PlanName>HEALTH REIMBURSEMENT ARRANGEMENT</PlanName>
<PlanName>HRA</PlanName>
</xsl:param>
<xsl:variable name="lowercase">abcdefghijklmnopqrstuvwxyz</xsl:variable>
<xsl:variable name="uppercase">ABCDEFGHIJKLMNOPQRSTUVWXYZ</xsl:variable>
<xsl:template match="/*">
<xsl:copy>
<xsl:for-each select="Eligibility_Detail_Record">
<xsl:variable name="pn" select="translate(EN_PLAN_NAME,$lowercase,$uppercase)"/>
<xsl:if test="msxsl:node-set($HRAPlanNames)/*[contains($pn,normalize-space())]">
<Eligibility_Detail_Record>
<xsl:copy-of select="EN_PLAN_NAME"/>
</Eligibility_Detail_Record>
</xsl:if>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
如果这不起作用,并且您不介意在 XSLT 中硬编码计划名称(不使用 xsl:param
),请尝试不使用 node-set()
的方法:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:var="http://schemas.microsoft.com/BizTalk/2003/var"
exclude-result-prefixes="msxsl var s0 ns0 local" version="1.0"
xmlns:s0="CDHC_Eligibility_LSDD"
xmlns:ns0="CDHC_Eligibility_LSDD_Internal"
xmlns:local="local">
<xsl:output omit-xml-declaration="yes" method="xml" version="1.0" />
<local:HRAPlanNames>
<local:PlanName>HEALTH REIMBURSEMENT ARRANGEMENT</local:PlanName>
<local:PlanName>HRA</local:PlanName>
</local:HRAPlanNames>
<xsl:variable name="planNames"
select="document('')/xsl:stylesheet/local:HRAPlanNames/local:PlanName"/>
<xsl:variable name="lowercase">abcdefghijklmnopqrstuvwxyz</xsl:variable>
<xsl:variable name="uppercase">ABCDEFGHIJKLMNOPQRSTUVWXYZ</xsl:variable>
<xsl:template match="/*">
<xsl:copy>
<xsl:for-each select="Eligibility_Detail_Record">
<xsl:variable name="pn" select="translate(EN_PLAN_NAME,$lowercase,$uppercase)"/>
<xsl:if test="$planNames[contains($pn,normalize-space())]">
<Eligibility_Detail_Record>
<xsl:copy-of select="EN_PLAN_NAME"/>
</Eligibility_Detail_Record>
</xsl:if>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
contains()
函数的两个参数的类型必须是string。您正在尝试将它与 node-set 作为第二个参数一起使用,并且(在 XSLT 1.0 中)这将导致 node-set 中只有第一个节点考虑过。
如果您想保留 HRAPlanNames
参数的当前结构,您需要执行以下操作:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
exclude-result-prefixes="msxsl" >
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="HRAPlanNames">
<PlanName>Health Reimbursement Arrangement</PlanName>
<PlanName>HRA</PlanName>
</xsl:param>
<xsl:template match="/*">
<EligibilityRecords xmlns="CDHC_Eligibility_LSDD_Internal">
<xsl:for-each select="Eligibility_Detail_Record">
<xsl:variable name="plan-name" select="EN_PLAN_NAME" />
<xsl:variable name="test">
<xsl:for-each select="msxsl:node-set($HRAPlanNames)/PlanName">
<xsl:if test="contains($plan-name, .)">Y</xsl:if>
</xsl:for-each>
</xsl:variable>
<xsl:if test="string($test)">
<xsl:copy-of select="."/>
</xsl:if>
</xsl:for-each>
</EligibilityRecords>
</xsl:template>
</xsl:stylesheet>
为了得到预期的结果。
我正在尝试将特定节点 (EN_PLAN_NAME) 中的文本与字符串列表进行比较,以便我可以仅输出包含与以下之一匹配的文本的节点那些字符串。我尝试使用这个类似问题的答案:
How to compare against multiple strings in xslt
输入XML
<EligibilityRecords xmlns="http://CDHC_Eligibility_LSDD">
<Eligibility_Detail_Record xmlns="">
<EN_PLAN_NAME>Health Savings Account</EN_PLAN_NAME>
<EN_MBRSHP_EFF_STRT_DT>01012017</EN_MBRSHP_EFF_STRT_DT>
</Eligibility_Detail_Record>
<Eligibility_Detail_Record xmlns="">
<EN_PLAN_NAME>zzHealth Reimbursement Arrangement</EN_PLAN_NAME>
<EN_MBRSHP_EFF_STRT_DT>01012017</EN_MBRSHP_EFF_STRT_DT>
</Eligibility_Detail_Record>
<Eligibility_Detail_Record xmlns="">
<EN_PLAN_NAME>Health Reimbursement Arrangement 233</EN_PLAN_NAME>
<EN_MBRSHP_EFF_STRT_DT>01012017</EN_MBRSHP_EFF_STRT_DT>
</Eligibility_Detail_Record>
<Eligibility_Detail_Record xmlns="">
<EN_PLAN_NAME>HRA</EN_PLAN_NAME>
<EN_MBRSHP_EFF_STRT_DT>01012017</EN_MBRSHP_EFF_STRT_DT>
</Eligibility_Detail_Record>
<Eligibility_Detail_Record xmlns="">
<EN_PLAN_NAME>BASE HRA</EN_PLAN_NAME>
<EN_MBRSHP_EFF_STRT_DT>01012017</EN_MBRSHP_EFF_STRT_DT>
</Eligibility_Detail_Record>
<Eligibility_Detail_Record xmlns="">
<EN_PLAN_NAME>FSA</EN_PLAN_NAME>
<EN_MBRSHP_EFF_STRT_DT>01012017</EN_MBRSHP_EFF_STRT_DT>
</Eligibility_Detail_Record>
</EligibilityRecords>
预期输出XML
<EligibilityRecords xmlns="CDHC_Eligibility_LSDD_Internal">
<Eligibility_Detail_Record xmlns="">
<EN_PLAN_NAME>zzHealth Reimbursement Arrangement</EN_PLAN_NAME>
<EN_MBRSHP_EFF_STRT_DT>01012017</EN_MBRSHP_EFF_STRT_DT>
</Eligibility_Detail_Record>
<Eligibility_Detail_Record xmlns="">
<EN_PLAN_NAME>Health Reimbursement Arrangement 233</EN_PLAN_NAME>
<EN_MBRSHP_EFF_STRT_DT>01012017</EN_MBRSHP_EFF_STRT_DT>
</Eligibility_Detail_Record>
<Eligibility_Detail_Record xmlns="">
<EN_PLAN_NAME>HRA</EN_PLAN_NAME>
<EN_MBRSHP_EFF_STRT_DT>01012017</EN_MBRSHP_EFF_STRT_DT>
</Eligibility_Detail_Record>
<Eligibility_Detail_Record xmlns="">
<EN_PLAN_NAME>BASE HRA</EN_PLAN_NAME>
<EN_MBRSHP_EFF_STRT_DT>01012017</EN_MBRSHP_EFF_STRT_DT>
</Eligibility_Detail_Record>
</EligibilityRecords>
XSLT
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:var="http://schemas.microsoft.com/BizTalk/2003/var"
exclude-result-prefixes="msxsl var s0 ns0" version="1.0"
xmlns:s0="CDHC_Eligibility_LSDD"
xmlns:ns0="CDHC_Eligibility_LSDD_Internal">
<xsl:output omit-xml-declaration="yes" method="xml" version="1.0" />
<xsl:param name="HRAPlanNames">
<PlanName>Health Reimbursement Arrangement</PlanName>
<PlanName>HRA</PlanName>
</xsl:param>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/*">
<ns0:EligibilityRecords>
<xsl:for-each select="Eligibility_Detail_Record">
<xsl:if test="contains(EN_PLAN_NAME,msxsl:node-set($HRAPlanNames)/*)">
<Eligibility_Detail_Record>
<xsl:copy-of select="EN_PLAN_NAME"/>
</Eligibility_Detail_Record>
</xsl:if>
</xsl:for-each>
</ns0:EligibilityRecords>
</xsl:template>
</xsl:stylesheet>
XSLT 输出任何 EN_PLAN_NAME 的文本包含 "Health Reimbursement Arrangement" 但不输出任何包含 "Health Reimbursement Arrangement" 的节点包含 "HRA"。我不确定我做错了什么。
注意:您可以从两个示例中取出 translate()
。在你编辑之前,我已经从你的问题中复制了输入内容。
我现在无法测试 msxsl,但试试这个:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:var="http://schemas.microsoft.com/BizTalk/2003/var"
exclude-result-prefixes="msxsl var s0 ns0" version="1.0"
xmlns:s0="CDHC_Eligibility_LSDD"
xmlns:ns0="CDHC_Eligibility_LSDD_Internal">
<xsl:output omit-xml-declaration="yes" method="xml" version="1.0" />
<xsl:param name="HRAPlanNames">
<PlanName>HEALTH REIMBURSEMENT ARRANGEMENT</PlanName>
<PlanName>HRA</PlanName>
</xsl:param>
<xsl:variable name="lowercase">abcdefghijklmnopqrstuvwxyz</xsl:variable>
<xsl:variable name="uppercase">ABCDEFGHIJKLMNOPQRSTUVWXYZ</xsl:variable>
<xsl:template match="/*">
<xsl:copy>
<xsl:for-each select="Eligibility_Detail_Record">
<xsl:variable name="pn" select="translate(EN_PLAN_NAME,$lowercase,$uppercase)"/>
<xsl:if test="msxsl:node-set($HRAPlanNames)/*[contains($pn,normalize-space())]">
<Eligibility_Detail_Record>
<xsl:copy-of select="EN_PLAN_NAME"/>
</Eligibility_Detail_Record>
</xsl:if>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
如果这不起作用,并且您不介意在 XSLT 中硬编码计划名称(不使用 xsl:param
),请尝试不使用 node-set()
的方法:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:var="http://schemas.microsoft.com/BizTalk/2003/var"
exclude-result-prefixes="msxsl var s0 ns0 local" version="1.0"
xmlns:s0="CDHC_Eligibility_LSDD"
xmlns:ns0="CDHC_Eligibility_LSDD_Internal"
xmlns:local="local">
<xsl:output omit-xml-declaration="yes" method="xml" version="1.0" />
<local:HRAPlanNames>
<local:PlanName>HEALTH REIMBURSEMENT ARRANGEMENT</local:PlanName>
<local:PlanName>HRA</local:PlanName>
</local:HRAPlanNames>
<xsl:variable name="planNames"
select="document('')/xsl:stylesheet/local:HRAPlanNames/local:PlanName"/>
<xsl:variable name="lowercase">abcdefghijklmnopqrstuvwxyz</xsl:variable>
<xsl:variable name="uppercase">ABCDEFGHIJKLMNOPQRSTUVWXYZ</xsl:variable>
<xsl:template match="/*">
<xsl:copy>
<xsl:for-each select="Eligibility_Detail_Record">
<xsl:variable name="pn" select="translate(EN_PLAN_NAME,$lowercase,$uppercase)"/>
<xsl:if test="$planNames[contains($pn,normalize-space())]">
<Eligibility_Detail_Record>
<xsl:copy-of select="EN_PLAN_NAME"/>
</Eligibility_Detail_Record>
</xsl:if>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
contains()
函数的两个参数的类型必须是string。您正在尝试将它与 node-set 作为第二个参数一起使用,并且(在 XSLT 1.0 中)这将导致 node-set 中只有第一个节点考虑过。
如果您想保留 HRAPlanNames
参数的当前结构,您需要执行以下操作:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
exclude-result-prefixes="msxsl" >
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="HRAPlanNames">
<PlanName>Health Reimbursement Arrangement</PlanName>
<PlanName>HRA</PlanName>
</xsl:param>
<xsl:template match="/*">
<EligibilityRecords xmlns="CDHC_Eligibility_LSDD_Internal">
<xsl:for-each select="Eligibility_Detail_Record">
<xsl:variable name="plan-name" select="EN_PLAN_NAME" />
<xsl:variable name="test">
<xsl:for-each select="msxsl:node-set($HRAPlanNames)/PlanName">
<xsl:if test="contains($plan-name, .)">Y</xsl:if>
</xsl:for-each>
</xsl:variable>
<xsl:if test="string($test)">
<xsl:copy-of select="."/>
</xsl:if>
</xsl:for-each>
</EligibilityRecords>
</xsl:template>
</xsl:stylesheet>
为了得到预期的结果。