使用特定节点及其后代的转义XML-String填充属性

时间:2017-10-16 15:13:09

标签: xml xslt

我有一个模板文件,相关部分如下所示:

<PipeSectionDefinition designation="Strang 1 RW/1-10" displayLastNode="true" drawMode="1" startPosition="0" pipeListId="xml:&lt;Pipes&gt;&#xD;&#xA; &lt;Pipe id=&quot;1A3352BC-8CFE-4D0C-BCCD-E30765B32821&quot; objectType=&quot;10000&quot; flowDirection=&quot;1&quot;/&gt;&#xD;&#xA; &lt;Pipe id=&quot;B9A3B241-C4DA-4925-BB4F-9564F645AEBD&quot; objectType=&quot;10000&quot; flowDirection=&quot;1&quot;/&gt;&#xD;&#xA;&lt;/Pipes&gt;&#xD;&#xA;" 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-to-string.xsl样式表以及与/匹配的模板。变量$Straenge指向我的“数据源”文件,该文件位于正在转换的文件旁边。

提前感谢您的帮助,如果您需要更多信息,请与我们联系!

1 个答案:

答案 0 :(得分:2)

由于您已经使用过XSLT 2,因此您可能使用Saxon 9作为XSLT处理器,而Saxon 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">

创建该属性值。