装满一个特定节点的转义XML字符串的属性和它的后代
问题描述:
我有一个模板文件,其中有关的部分看起来像这样:装满一个特定节点的转义XML字符串的属性和它的后代
<PipeSectionDefinition designation="Strang 1 RW/1-10" displayLastNode="true" drawMode="1" startPosition="0" pipeListId="xml:<Pipes>
 <Pipe id="1A3352BC-8CFE-4D0C-BCCD-E30765B32821" objectType="10000" flowDirection="1"/>
 <Pipe id="B9A3B241-C4DA-4925-BB4F-9564F645AEBD" objectType="10000" flowDirection="1"/>
</Pipes>
" pipeLayer.ref="76037019-658c-41d5-b422-017f91e36701" nodeLayer.ref="03e6f262-bdb4-4684-b4bf-bb239feaad95">
<CrossingPipes textVisible="true" lineVisible="true" lineWidth="0" positionVisible="true" symbolVisible="true" textOPath="Concat('DN ', RefObject.Cast(GeoObjectLineBase).Cast(GeoObjectLine01).Hoehe, ' SO: ', FormatNumber(GeoHeight, 3))" />
<NodeConnections lineWidth="0" />
<PipeConnections textVisible="true" lineVisible="true" lineWidth="0" positionVisible="true" symbolVisible="true" textOPath="Concat('DN ', Profilhoehe, ' SO: ', FormatNumber(RohrsohleAblauf, 3))" symbolLayer.ref="679e499d-022d-475e-bd76-8c7f7fa1aad8" textLayer.ref="679e499d-022d-475e-bd76-8c7f7fa1aad8" lineLayer.ref="679e499d-022d-475e-bd76-8c7f7fa1aad8" />
<InletPipes lineWidth="0" />
<OutletPipes lineWidth="0" symbolLayer.ref="03e6f262-bdb4-4684-b4bf-bb239feaad95" />
<PipePoints textVisible="true" lineVisible="true" lineWidth="0" positionVisible="true" symbolVisible="true" lineLayer.ref="67877b9d-2de9-4764-9201-d02fbce8148f" />
<SpecialPoints textVisible="true" lineVisible="true" lineWidth="0" positionVisible="true" symbolVisible="true" textOPath="FormatNumber(GeoHeight, 3)" />
<TerrainPoints textVisible="true" lineVisible="true" lineWidth="0" positionVisible="true" symbolVisible="true" textOPath="FormatNumber(GeoHeight, 3)" lineLayer.ref="dbc6c898-6686-4be0-bc9c-9d15517258a5" />
<AttributeSegments lineWidth="0" />
<AllAttributes distanceBetweenSectionLineAndText="20" textHeight="1.8" />
</PipeSectionDefinition>
可能有多个,这些PipeSectionDefintion
元素,但我只是使用第一个作为我的模板。有趣的部分是pipeListId
属性。
我的“数据源”是这样的文件:
<StrangList>
<Pipes Bezeichnung="Strang 15b-SW" HaltungenOhneReihenfolge="0">
<Pipe objectType="10000" flowDirection="1" Strang="Strang 15b-SW" Bezeichnung="7b - 7a" Reihenfolge="1" id="C9B982E1-82C0-4552-AF3D-03E3B9B8936A"/>
<Pipe objectType="10000" flowDirection="1" Strang="Strang 15b-SW" Bezeichnung="7a - 7" Reihenfolge="0" id="CF363D66-8C31-43C2-A5B7-575D3A6D02F5"/>
</Pipes>
<Pipes Bezeichnung="Strang 16a SW" HaltungenOhneReihenfolge="0">
<Pipe objectType="10000" flowDirection="1" Strang="Strang 16a SW" Bezeichnung="3 - 2" Reihenfolge="2" id="37D88A6F-D449-4296-B696-AE9FA129F9E9"/>
<Pipe objectType="10000" flowDirection="1" Strang="Strang 16a SW" Bezeichnung="2 - 1" Reihenfolge="1" id="0693B8E5-108B-4877-BC02-10157C681FA3"/>
<Pipe objectType="10000" flowDirection="1" Strang="Strang 16a SW" Bezeichnung="1 - 6a" Reihenfolge="0" id="FC683422-DC7C-4050-865E-C87D4B49BD79"/>
</Pipes>
</StrangList>
首先,我想谋杀谁把一个转义XML的文档转换成一个属性值的人,但其次,我需要做同样的事情发生,所以他的愚蠢程序做它应该做的。
侦测到的,该属性的值是这样的:
xml:<Pipes>
<Pipe id="1A3352BC-8CFE-4D0C-BCCD-E30765B32821" objectType="10000" flowDirection="1"/>
<Pipe id="B9A3B241-C4DA-4925-BB4F-9564F645AEBD" objectType="10000" flowDirection="1"/>
</Pipes>
因此,大家可以看到现在,我的“数据源”看起来几乎一样,属性的倍数,有一些额外的属性。如果他们来这里旅行,这应该不成问题。所以我需要做的是将我的每个Pipes
元素转换为一个转义字符串,以“xml:”为前缀,然后将其作为该属性的值。我现在的样式看起来是这样的:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:import href="file:/C:/Java/xml-to-string.xsl"/>
<xsl:output indent="yes"/>
<xsl:variable name="Straenge" select="replace(document-uri(/), tokenize(document-uri(/), '/')[last()], 'Straenge.xml')"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*" mode="local"/>
</xsl:copy>
</xsl:template>
<xsl:template match="PipeSections" mode="local">
<xsl:variable name="template" select="PipeSectionDefinition[1]"/>
<xsl:for-each select="document($Straenge)/StrangList/Pipes">
<xsl:variable name="Pipes" select="."/>
<xsl:variable name="PipesText">
<xsl:call-template name="xml-to-string">
<xsl:with-param name="node-set"><xsl:value-of select="$Pipes"/></xsl:with-param>
</xsl:call-template>
</xsl:variable>
<xsl:element name="PipeSectionDefinition">
<xsl:attribute name="designation" select="@Bezeichnung"/>
<xsl:attribute name="displayLastNode" select="$template/@displayLastNode"/>
<xsl:attribute name="drawMode" select="$template/@drawMode"/>
<xsl:attribute name="startPosition" select="$template/@startPosition"/>
<xsl:attribute name="pipeListId"/>
<xsl:attribute name="pipeLayer.ref" select="$template/@pipeLayer.ref"/>
<xsl:attribute name="nodeLayer.ref" select="$template/@nodeLayer.ref"/>
<xsl:copy-of select="$template/child::node()"/>
</xsl:element>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
它使用从http://lenzconsulting.com/xml-to-string/的XML到string.xsl样式相匹配/
注释掉的模板。变量$Straenge
指向我的“数据源”文件,该文件位于正在转换的文件的旁边。
在此先感谢您的帮助,并让我知道您是否需要更多信息!
答
正如你已经使用XSLT 2你可能使用撒克逊9作为XSLT处理器和撒克逊9.8(在所有版本包括开源HE版)支持XSLT 3.0和中的XPath 3.0/3.1 serialize
功能(https://www.w3.org/TR/xpath-functions-31/#func-serialize)你可能根本不需要导入的样式表,但可以简单地切换到最新的Saxon版本和XSLT 3.0并使用例如
<xsl:attribute name="pipeListId" select="'xml:' || serialize(.)"/>
的
<xsl:for-each select="document($Straenge)/StrangList/Pipes">
内创建属性值。
我没有给你答案,但是我觉得你不得不在XML中嵌入转义的XML。 – Steve
那么究竟是什么问题,如果你有'xml-to-string.xsl'样式表并调用它的模板来填充你的'PipesText'变量,为什么不用它的值来填充'pipeListId'属性呢?一般来说,当您使用XSLT 2.0并且许多人使用Saxon来运行它时,请注意所有版本(包括HE)中的Saxon 9.8都支持XPath 3.0/3.1'serialize'函数,所以您甚至不需要导入用于序列化/ XML到字符串任务的样式表。 –
@MartinHonnen请添加,作为一个实际的答案,因为这已经解决了我的问题。而我的问题是,上面的样式表没有填充任何东西,不是我认为它应该在当前状态下的变量,也不是如果我改变它的属性。但是'serialize()'是解决方案,因为我使用了Saxon。 – Pipelynx