使用XSLT 2.0,如何根据下面的规则/要求动态处理XML文档以删除具有xml:lang
属性的节点?
要求:
xml:lang
xml:lang
值具有基于语言/区域设置的3层层次结构,下面是非详尽的示例:
示例数据集:
<?xml version="1.0" encoding="UTF-8"?>
<arbitrarydepth>
<scenario1 xml:lang="x-default">A Default Node Value</scenario1>
<scenario1 xml:lang="en">A Default Node Value</scenario1>
<scenario1 xml:lang="en-US">A Default Node Value</scenario1>
<scenario2 xml:lang="x-default">The orig value</scenario2>
<scenario2 xml:lang="en">The orig value</scenario2>
<scenario2 xml:lang="en-US">A new value</scenario2>
<scenario3 xml:lang="x-default">The orig value</scenario3>
<scenario3 xml:lang="en">A new value</scenario3>
<scenario3 xml:lang="en-US">The orig value</scenario3>
<scenario4 xml:lang="x-default">The orig value</scenario4>
<scenario4 xml:lang="en">An english value</scenario4>
<scenario4 xml:lang="en-US">An english US value</scenario4>
<scenario4 xml:lang="fr">A french value</scenario4>
<scenario4 xml:lang="fr-FR">A french value</scenario4>
<scenario4 xml:lang="fr-CA">A french Canada value</scenario4>
<scenario5 xml:lang="x-default" attr0="something here">The orig value</scenario5>
<scenario5 xml:lang="en" attr1="Some attribute">The orig value</scenario5>
<scenario5 xml:lang="en-US" attr2="some other attribute">The orig value</scenario5>
<scenario5 xml:lang="fr" attr0="something here">The orig value</scenario5>
<scenario5 xml:lang="fr-FR">The orig value</scenario5>
</arbitrarydepth>
示例结果集:
<?xml version="1.0" encoding="UTF-8"?>
<arbitrarydepth>
<scenario1 xml:lang="x-default">A Default Node Value</scenario1>
<scenario2 xml:lang="x-default">The orig value</scenario2>
<scenario2 xml:lang="en-US">A new value</scenario2>
<scenario3 xml:lang="x-default">The orig value</scenario3>
<scenario3 xml:lang="en">A new value</scenario3>
<scenario3 xml:lang="en-US">The orig value</scenario3>
<scenario4 xml:lang="x-default">The orig value</scenario4>
<scenario4 xml:lang="en">An english value</scenario4>
<scenario4 xml:lang="en-US">An english US value</scenario4>
<scenario4 xml:lang="fr">A french value</scenario4>
<scenario4 xml:lang="fr-CA">A french Canada value</scenario4>
<scenario5 xml:lang="x-default" attr0="something here">The orig value</scenario5>
<scenario5 xml:lang="en" attr1="Some attribute">The orig value</scenario5>
<scenario5 xml:lang="en-US" attr2="some other attribute">The orig value</scenario5>
</arbitrarydepth>
答案 0 :(得分:1)
这应该满足所有要求,除了最后一个关于匹配动态属性的要求:
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:template match="*">
<xsl:variable name="elementName" select="name()"/>
<xsl:variable name="contentText" select="normalize-space(.)"/>
<xsl:choose>
<xsl:when test="not(@xml:lang)">
<!-- Non-lang element -->
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates select="*"/>
</xsl:copy>
</xsl:when>
<xsl:when test="@xml:lang='x-default'">
<!-- Tier 1: xml:lang="x-default" -->
<xsl:copy-of select="."/>
</xsl:when>
<xsl:when test="contains(@xml:lang,'-')">
<!-- Tier 3: xml:lang="en-US" -->
<xsl:variable name="baselang" select="substring-before(@xml:lang, '-')"/>
<xsl:choose>
<xsl:when test="../*[name()=$elementName][@xml:lang=$baselang][normalize-space(.)=$contentText]">
<!-- Same text as Tier 2 parent -->
</xsl:when>
<xsl:when test="../*[name()=$elementName][@xml:lang=$baselang]">
<xsl:copy-of select="."/>
</xsl:when>
<xsl:when test="../*[name()=$elementName][@xml:lang='x-default'][normalize-space(.)=$contentText]">
<!-- Same text as Tier 1 parent -->
</xsl:when>
<xsl:when test="../*[name()=$elementName][@xml:lang='x-default']">
<xsl:copy-of select="."/>
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="."/>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<!-- Tier 2: xml:lang="en" -->
<xsl:choose>
<xsl:when test="../*[name()=$elementName][@xml:lang='x-default'][normalize-space(.)=$contentText]">
<!-- Same text as Tier 1 parent -->
</xsl:when>
<xsl:when test="../*[name()=$elementName][@xml:lang='x-default']">
<xsl:copy-of select="."/>
</xsl:when>
<xsl:otherwise>
<!-- No matching parent -->
<xsl:copy-of select="."/>
</xsl:otherwise>
</xsl:choose>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
演示:http://www.xsltcake.com/slices/uopn40
匹配父级和子级之间的动态属性实际上非常复杂。您必须循环使用属性并与当前父级进行比较。如果父项上缺少任何属性,或者它的值不同,则必须保留新元素。
为了满足最后的要求,我认为你必须转向命令式语言(C#,JavaScript,Java)。