gpt4 book ai didi

xslt - 将连续的后代节点合并为一个

转载 作者:行者123 更新时间:2023-12-03 15:59:40 26 4
gpt4 key购买 nike

XML:

<t>
<ScreenSize>
<Width>1440</Width>
<Height>900</Height>
</ScreenSize>
<ConfigurationHotSpots>
<Rectangle>
<Location>
<X>0</X>
<Y>0</Y>
</Location>
<Size>
<Width>50</Width>
<Height>50</Height>
</Size>
<X>0</X>
<Y>0</Y>
<Width>50</Width>
<Height>50</Height>
</Rectangle>
</ConfigurationHotSpots>
</t>

所需的输出 XML:

<t>
<ScreenSizeWidth>1440</ScreenSizeWidth>
<ScreenSizeWidth>900</ScreenSizeWidth>
<ConfigurationHotSpotsRectangleLocationX>0</ConfigurationHotSpotsRectangleLocationX>
<ConfigurationHotSpotsRectangleLocationY>0</ConfigurationHotSpotsRectangleLocationY>
<ConfigurationHotSpotsRectangleSizeWidth>50</ConfigurationHotSpotsRectangleSizeWidth>
<ConfigurationHotSpotsRectangleSizeHeight>50</ConfigurationHotSpotsRectangleSizeHeight>
<ConfigurationHotSpotsRectangleX>0</ConfigurationHotSpotsRectangleX>
<ConfigurationHotSpotsRectangleY>0</ConfigurationHotSpotsRectangleY>
<ConfigurationHotSpotsRectangleWidth>50</ConfigurationHotSpotsRectangleWidth>
<ConfigurationHotSpotsRectangleHeight>50</ConfigurationHotSpotsRectangleHeight>
</t>

规则:

  • 对于已定义节点集中的每个元素(在本例中为 <ScreenSize> | <ConfigurationHotSpots>),执行以下操作:处理所有叶子后代(即没有子代的那些),以便创建一个新元素;这个新元素的名称应该是当前节点和无子后代之间所有元素的串联。
  • 在整个文档中这些“ block ”的数量是可变的,因此没有手动模板(即只处理 <ScreenSize> 的后代的模板,只处理 <ConfigurationHotSpots> 的后代的模板,等等)

我目前拥有的:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output omit-xml-declaration="no" indent="yes" />
<xsl:strip-space elements="*" />

<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*" />
</xsl:copy>
</xsl:template>

<xsl:template match="ScreenSize|ConfigurationHotSpots">
<xsl:apply-templates select="descendant::*[not(*)]" mode="descendants" />
</xsl:template>

<xsl:template match="*" mode="descendants">
<xsl:element name="{concat(name(ancestor::*[not(self::t)]), name())}">
<xsl:apply-templates />
</xsl:element>
</xsl:template>

</xsl:stylesheet>

问题似乎是 name(ancestor::*[not(self::t)])部分;它没有做我希望它做的事情(神奇地输出这些元素的名称,一个接一个)。相反,这是我得到的:

<?xml version="1.0" encoding="UTF-8"?>
<t>
<ScreenSizeWidth>1440</ScreenSizeWidth>
<ScreenSizeHeight>900</ScreenSizeHeight>
<ConfigurationHotSpotsX>0</ConfigurationHotSpotsX>
<ConfigurationHotSpotsY>0</ConfigurationHotSpotsY>
<ConfigurationHotSpotsWidth>50</ConfigurationHotSpotsWidth>
<ConfigurationHotSpotsHeight>50</ConfigurationHotSpotsHeight>
<ConfigurationHotSpotsX>0</ConfigurationHotSpotsX>
<ConfigurationHotSpotsY>0</ConfigurationHotSpotsY>
<ConfigurationHotSpotsWidth>50</ConfigurationHotSpotsWidth>
<ConfigurationHotSpotsHeight>50</ConfigurationHotSpotsHeight>
</t>

提前致谢!

最佳答案

执行 name(ancestor::*[not(self::t)]) 将不会返回名称列表,而只会返回它匹配的最后一个名称(或者它是首先?)。

您可以采用一种略有不同的方法,与您目前正在做的相差不远,而不是直接跳到“叶”元素,依次匹配每个级别,但保持元素名称的连续串联,它们通过参数从一层传递到另一层。

试试这个 XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="ScreenSize|ConfigurationHotSpots">
<xsl:apply-templates mode="descendants">
<xsl:with-param name="name" select="local-name()" />
</xsl:apply-templates>
</xsl:template>

<xsl:template match="*" mode="descendants">
<xsl:param name="name" />
<xsl:apply-templates mode="descendants">
<xsl:with-param name="name" select="concat($name, local-name())" />
</xsl:apply-templates>
</xsl:template>

<xsl:template match="*[not(*)]" mode="descendants">
<xsl:param name="name" />
<xsl:element name="{concat($name, local-name())}">
<xsl:value-of select="." />
</xsl:element>
</xsl:template>

<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>

应用于示例 XML 时,输出如下

<t>
<ScreenSizeWidth>1440</ScreenSizeWidth>
<ScreenSizeHeight>900</ScreenSizeHeight>
<ConfigurationHotSpotsRectangleLocationX>0</ConfigurationHotSpotsRectangleLocationX>
<ConfigurationHotSpotsRectangleLocationY>0</ConfigurationHotSpotsRectangleLocationY>
<ConfigurationHotSpotsRectangleSizeWidth>50</ConfigurationHotSpotsRectangleSizeWidth>
<ConfigurationHotSpotsRectangleSizeHeight>50</ConfigurationHotSpotsRectangleSizeHeight>
<ConfigurationHotSpotsRectangleX>0</ConfigurationHotSpotsRectangleX>
<ConfigurationHotSpotsRectangleY>0</ConfigurationHotSpotsRectangleY>
<ConfigurationHotSpotsRectangleWidth>50</ConfigurationHotSpotsRectangleWidth>
<ConfigurationHotSpotsRectangleHeight>50</ConfigurationHotSpotsRectangleHeight>
</t>

关于xslt - 将连续的后代节点合并为一个,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12396123/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com