使用 XSLT 1.0 进行多项更改(大写元素首字母、顺序元素、聚合/组元素)
Posted
技术标签:
【中文标题】使用 XSLT 1.0 进行多项更改(大写元素首字母、顺序元素、聚合/组元素)【英文标题】:Make multiple changes with XLST 1.0 (uppercase element first letter, order elements, aggrate/group elements) 【发布时间】:2021-02-23 20:48:59 【问题描述】:我的输入 xml 看起来像这样:
<myFamily>
<spouse type="1">Halle Berry</spouse>
<parent type="bio">Jane Smith-Doe</parent>
<spouse type="2">Eva Longoria</spouse>
<uncle type="paternal">Bob Beam</uncle>
<parent type="bio">Jim Beam</parent>
<uncle type="maternal">Mike Smith</uncle>
<aunt type="paternal">Viola Davis</aunt>
<inLaw type="mother">Dr. Curry-Pepper</inLaw>
<brother name="Ron Isley">
<child>Sara Isley</child>
<child>Ron Isley Jr.</child>
<child>Martha Isley-Focker</child>
</brother>
<parent type="step">Jon Doe</parent>
<inLaw type="father">Dr. Pepper</inLaw>
<spouse type="3">Sofia Vergara</spouse>
<uncle type="paternal">Bo Beam</uncle>
<spouse type="3">Sonya Curry</spouse>
<Sister name ="Shelly Isley"/>
</myFamily>
我希望它以这样的方式结束:
<MyFamily>
<Parents>
<Parent type="bio">Jane Smith-Doe</Parent>
<Parent type="bio">Jim Beam</Parent>
<Parent type="step">Jon Doe</Parent>
</Parents>
<Siblings>
<Sister name ="Shelly Isley"/>
<Brother name="Ron Isley">
<Child>Sara Isley</Child>
<Child>Ron Isley Jr.</Child>
<Child>Martha Isley-Focker</Child>
</Brother>
<Siblings>
<Uncles>
<Uncle type="paternal">Bob Beam</Uncle>
<Uncle type="maternal">Mike Smith</Uncle>
<Uncle type="paternal">Bo Beam</Uncle>
</Uncles>
<Aunts><Aunt type="paternal">Viola Davis</Aunt><Aunts>
<InLaws>
<InLaw type="mother">Dr. Curry-Pepper</InLaw>
<InLaw type="father">Dr. Pepper</InLaw>
</InLaws>
<Wives>
<Wife type="1">Halle Berry</Wife>
<Wife type="2">Eva Longoria</Wife>
<Wife type="3">Sofia Vergara</Wife>
<Wife type="3">Sonya Curry</Wife>
</Wives>
</MyFamily>
要使第一个字母大写,重命名配偶,并以某种方式排序我试过这个,但没有用:
<xsl:template match="@*|node()">
<xsl:copy>
<!-- Order Section Nodes -->
<xsl:apply-templates select="myFamily[(SectionName = 'parent')]" mode="nodeCopy"/>
<xsl:apply-templates select="myFamily[(SectionName = 'sister')]" mode="nodeCopy"/>
<xsl:apply-templates select="myFamily[(SectionName = 'brother')]" mode="nodeCopy"/>
<xsl:apply-templates select="myFamily[(SectionName = 'unle')]" mode="nodeCopy"/>
<xsl:apply-templates select="myFamily[(SectionName = 'aunt')]" mode="nodeCopy"/>
<xsl:apply-templates select="myFamily[(SectionName = 'inLaw')]" mode="nodeCopy"/>
<xsl:apply-templates select="myFamily[(SectionName = 'spouse')]" mode="nodeCopy"/>
<!-- List All Remaining Nodes and Remove ones that have already been ordered above -->
<xsl:apply-templates select="@*|node()[not(parent | sister | brother | spouse | uncle | aunt | inLaw)]"/>
</xsl:copy>
</xsl:template>
<!-- Rename spouse Nodes -->
<xsl:template match="spouse">
<Wife><xsl:apply-templates select="@*|node()" mode="nodeCopy"/></Wife>
</xsl:template>
<!-- Uppercase first letter of elements -->
<xsl:template match="*">
<xsl:element name="concat(
translate(subsstring(name(.),1,1), $vLower, $vUpper),
substring(name(.), 2, string-length(name(.))-1)
)">
<xsl:apply-templates select="@*|node()"/>
</xsl:element>
</xsl:template>
关于我想要分组的方式,我觉得这可能适用(https://***.com/a/16818842/5517100),但我不明白。老实说,我几乎看不懂。
【问题讨论】:
请一次问一个问题。 WRT 了解 XSLT 1.0 分组,建议您阅读:jenitennison.com/xslt/grouping/muenchian.html。尽管使用预定义的组,您可能不需要它。 由于标题大小写不匹配(即<Child>Sara Isley</child>
),您想要的结果格式不正确。请记住 XML 区分大小写。为什么是<Aunt>
标题大小写而不是<uncle>
?您正在寻找的解决方案的通用性如何?配偶永远是妻子吗?为什么不只通过那些根部分(即所有父母、所有兄弟姐妹等)检索节点?这感觉像是一个课程作业问题。
哎呀....意味着 em 匹配大写。这是一个剪切和粘贴失败
【参考方案1】:
使用示例中所示的预定义组,您可以简单地执行以下操作:
<xsl:template match="/myFamily">
<MyFamily>
<Parents>
<xsl:apply-templates select="parent"/>
</Parents>
<Siblings>
<xsl:apply-templates select="brother | sister"/>
</Siblings>
<!-- continue for other groups -->
</MyFamily>
</xsl:template>
或者,如果您希望省略空组:
<xsl:template match="/myFamily">
<MyFamily>
<xsl:variable name="parents" select="parent" />
<xsl:if test="$parents">
<Parents>
<xsl:apply-templates select="$parents"/>
</Parents>
</xsl:if>
<!-- continue for other groups -->
</MyFamily>
</xsl:template>
【讨论】:
这很有帮助。不敢相信我没想到。如何使嵌套元素也大写?使用这种方法的方法太多了。此答案会将*
的模板 - 与样式表中的最后一个模板相同。以上是关于使用 XSLT 1.0 进行多项更改(大写元素首字母、顺序元素、聚合/组元素)的主要内容,如果未能解决你的问题,请参考以下文章
xslt 不会选择在 XSLT 转换中动态更改名称空间以进行进一步转换