Xml muenchian分组从xsl键创建节点
使用xsl键解析一些唯一的条目,并使用键中的键值创建新节点 以下xml文件:Xml muenchian分组从xsl键创建节点,xml,xslt,muenchian-grouping,Xml,Xslt,Muenchian Grouping,使用xsl键解析一些唯一的条目,并使用键中的键值创建新节点 以下xml文件: <Services> <Service Name="Publish" TypeName="FzUDP.Publish" ProviderName="FzUDP" Position="69,102.533530201483" InitPriority="1"> <Parameter Name="MultiCastIp" Value="224.0.0.0"
<Services>
<Service Name="Publish" TypeName="FzUDP.Publish" ProviderName="FzUDP" Position="69,102.533530201483" InitPriority="1">
<Parameter Name="MultiCastIp" Value="224.0.0.0" />
<Parameter Name="MultiCastPort" Value="61499" />
<Parameter Name="Encryption" Value="0" />
<Parameter Name="PacketFormat" Value="0" />
</Service>
<Service Name="Subscribe" TypeName="FzUDP.Subscribe" ProviderName="FzUDP_1" Position="547,107.533530201483" InitPriority="2">
<Parameter Name="MultiCastIp" Value="224.0.0.0" />
<Parameter Name="MultiCastPort" Value="61499" />
<Parameter Name="Decryption" Value="0" />
<Parameter Name="PacketFormat" Value="0" />
</Service>
<Service Name="Subscribe2" TypeName="FzUDP.Subscribe" ProviderName="FzUDP_1" Position="547,107.533530201483" InitPriority="2">
<Parameter Name="MultiCastIp" Value="224.0.0.0" />
<Parameter Name="MultiCastPort" Value="61499" />
<Parameter Name="Decryption" Value="0" />
<Parameter Name="PacketFormat" Value="0" />
</Service>
</Services>
所以我认为服务元素需要在ServiceProviders之后创建,但参数元素可能可以被复制。我该怎么办
编辑1:我使用XSLT2.0获得了以下内容
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:saxon="http://saxon.sf.net/"
extension-element-prefixes="saxon"
xmlns:bootFile="http://tempuri.org/BootfileDefinition"
xmlns:apps="http://tempuri.org/FZDevice">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match ="//apps:Services">
<xsl:element name="ServiceProviders">
<xsl:for-each-group select="//apps:Service" group-by="//apps:Service/@ProviderName">
<xsl:element name="ServiceProvider">
<xsl:attribute name="Name">
<xsl:value-of select="current-grouping-key()"/>
</xsl:attribute>
<xsl:attribute name="TypeName">
<xsl:value-of select="tokenize(current-group()[1]/@TypeName, '\.')[1]"/>
</xsl:attribute>
<xsl:for-each select="current-group()">
<xsl:element name="Service">
<xsl:attribute name="Name">
<xsl:value-of select="@Name"/>
</xsl:attribute>
<xsl:attribute name="TypeName">
<xsl:value-of select="tokenize(@TypeName, '\.')[2]"/>
</xsl:attribute>
<xsl:attribute name="InitPriority">
<xsl:value-of select="@InitPriority"/>
</xsl:attribute>
<xsl:copy-of select="//apps:Parameter"/>
</xsl:element>
</xsl:for-each>
</xsl:element>
</xsl:for-each-group>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
请注意,元素名称前面有名称空间。我会在输出XML中去掉它们,如果有人能帮助我在XSLT 1.0中做同样的事情,我将不胜感激。考虑一下Muenchian分组的这种调整,因为您不需要身份转换,而是需要根据分组密钥重新编写服务模板。此外,要按时段拆分
@TypeName
内容,请使用前的子字符串和后的子字符串。您似乎希望
是@ProviderName
和@TypeName
的串联(在句点部分之前)
输出
<?xml version="1.0" encoding="utf-8"?>
<ServiceProviders>
<ServiceProvider Name="FzUDP" TypeName="FzUDP">
<Service Name="Publish" TypeName="Publish" InitPriority="1">
<Parameter Name="MultiCastIp" Value="224.0.0.0" />
<Parameter Name="MultiCastPort" Value="61499" />
<Parameter Name="Encryption" Value="0" />
<Parameter Name="PacketFormat" Value="0" />
</Service>
</ServiceProvider>
<ServiceProvider Name="FzUDP_1" TypeName="FzUDP">
<Service Name="Subscribe" TypeName="Subscribe" InitPriority="2">
<Parameter Name="MultiCastIp" Value="224.0.0.0" />
<Parameter Name="MultiCastPort" Value="61499" />
<Parameter Name="Decryption" Value="0" />
<Parameter Name="PacketFormat" Value="0" />
</Service>
<Service Name="Subscribe2" TypeName="Subscribe" InitPriority="2">
<Parameter Name="MultiCastIp" Value="224.0.0.0" />
<Parameter Name="MultiCastPort" Value="61499" />
<Parameter Name="Decryption" Value="0" />
<Parameter Name="PacketFormat" Value="0" />
</Service>
</ServiceProvider>
</ServiceProviders>
您能用几句话解释一下这里的实际问题吗?您似乎希望按ProviderName
属性对服务进行分组。为什么有必要标记任何东西?如果您使用的是XSLT2.0,为什么需要使用Muenchian分组?为什么结果中的Subscribe2
位于FzUDP_1
下?当输入中没有这样的元素时,为什么有一个匹配FourZeroBootFile/Runtime
的模板呢?是的,这是正确的。我已经纠正了问题中的错误。所以在XSLT2.0中有更好的方法吗?我仍然不理解您的输出。但是如果我说的是真的,那么你可以简单地使用
。这里有很多这样的分组例子,我确实找到了这样的例子,但是没有一个是关于我的具体案例的,因为除了分组之外还有更多的修改。
a. Attribute Position is not required in the transformed XML.
b. The TypeName attribute of the ServiceProvider element is the first '.' split of the TypeName attribute of the Service element.
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:saxon="http://saxon.sf.net/"
extension-element-prefixes="saxon"
xmlns:bootFile="http://tempuri.org/BootfileDefinition"
xmlns:apps="http://tempuri.org/FZDevice">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match ="//apps:Services">
<xsl:element name="ServiceProviders">
<xsl:for-each-group select="//apps:Service" group-by="//apps:Service/@ProviderName">
<xsl:element name="ServiceProvider">
<xsl:attribute name="Name">
<xsl:value-of select="current-grouping-key()"/>
</xsl:attribute>
<xsl:attribute name="TypeName">
<xsl:value-of select="tokenize(current-group()[1]/@TypeName, '\.')[1]"/>
</xsl:attribute>
<xsl:for-each select="current-group()">
<xsl:element name="Service">
<xsl:attribute name="Name">
<xsl:value-of select="@Name"/>
</xsl:attribute>
<xsl:attribute name="TypeName">
<xsl:value-of select="tokenize(@TypeName, '\.')[2]"/>
</xsl:attribute>
<xsl:attribute name="InitPriority">
<xsl:value-of select="@InitPriority"/>
</xsl:attribute>
<xsl:copy-of select="//apps:Parameter"/>
</xsl:element>
</xsl:for-each>
</xsl:element>
</xsl:for-each-group>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
<?xml version="1.0" encoding="utf-8"?>
<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" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="uniqueProviders" match="Service" use="concat(@ProviderName, substring-before(@TypeName, '.'))" />
<xsl:template match="/Services">
<ServiceProviders>
<xsl:apply-templates select="Service"/>
</ServiceProviders>
</xsl:template>
<xsl:template match="Service[generate-id() = generate-id(key('uniqueProviders', concat(@ProviderName, substring-before(@TypeName, '.')))[1])]">
<ServiceProvider Name="{@ProviderName}" TypeName="{substring-before(@TypeName, '.')}">
<xsl:for-each select="key('uniqueProviders', concat(@ProviderName, substring-before(@TypeName, '.')))">
<Service Name="{@Name}" TypeName="{substring-after(@TypeName, '.')}" InitPriority="{@InitPriority}">
<xsl:copy-of select="*"/>
</Service>
</xsl:for-each>
</ServiceProvider>
</xsl:template>
</xsl:stylesheet>
<?xml version="1.0" encoding="utf-8"?>
<ServiceProviders>
<ServiceProvider Name="FzUDP" TypeName="FzUDP">
<Service Name="Publish" TypeName="Publish" InitPriority="1">
<Parameter Name="MultiCastIp" Value="224.0.0.0" />
<Parameter Name="MultiCastPort" Value="61499" />
<Parameter Name="Encryption" Value="0" />
<Parameter Name="PacketFormat" Value="0" />
</Service>
</ServiceProvider>
<ServiceProvider Name="FzUDP_1" TypeName="FzUDP">
<Service Name="Subscribe" TypeName="Subscribe" InitPriority="2">
<Parameter Name="MultiCastIp" Value="224.0.0.0" />
<Parameter Name="MultiCastPort" Value="61499" />
<Parameter Name="Decryption" Value="0" />
<Parameter Name="PacketFormat" Value="0" />
</Service>
<Service Name="Subscribe2" TypeName="Subscribe" InitPriority="2">
<Parameter Name="MultiCastIp" Value="224.0.0.0" />
<Parameter Name="MultiCastPort" Value="61499" />
<Parameter Name="Decryption" Value="0" />
<Parameter Name="PacketFormat" Value="0" />
</Service>
</ServiceProvider>
</ServiceProviders>