输出整个XML作为属性(Output entire XML as an attribute)

2019-06-26 11:18发布

我是相当新的XML和XSL样式表,我一直在负责为我们的客户创造一个样式表。 我已经创建了输出下面格式的XML样式表:

<Trip TripType="Normal">
    <Plan BeginTime="2011-08-13T10:00:00" UserDefinedTripID="777" UserDefinedRouteID="777">
        <PlanStop ArrivalTime="2011-08-13T15:30:00" ArrivalLock="true" SiteID="1" PassThru1="test1" PassThru2="test2" PassThru3="test3" PassThru4="test4">
            <PlanNote Line1="Freeform Text" Line2="Line2" Line3="Line3" />
            <PlanCargo Duration="60" BillID="" Weight="100" Units="100.0" XUnitTypeID="10" Action="Pick" />
            <PlanNote Line1="Freeform Text" Line2="Line2" Line3="Line3" />
            <PlanCargo Duration="60" BillID="" Weight="100" Units="100.0" XUnitTypeID="12" Action="Pick" />
        </PlanStop>
    </Plan>
</Trip>

我需要输出和内容插入旅行元素中的属性看起来像这样:

<Trip TripID="-1" CurrentRevisionNumber="1" IsDispatch="1" IsActive="0" 
IsComplete="0" OrganizationID="4"
TripData="&lt;Trip TripType=&quot;Normal&quot;&gt;
  &lt;Plan BeginTime=&quot;2011-08-13T10:00:00&quot; UserDefinedTripID=&quot;777&quot;
  UserDefinedRouteID=&quot;777&quot;&gt;
    &lt;PlanStop ArrivalTime=&quot;2011-08-13T10:00:00&quot; ArrivalLock=&    quot;true&quot; SiteID=&quot;1&quot; PassThru1=&quot;test1&quot; PassThru2=&    quot;test2&quot; PassThru3=&quot;test3&quot; PassThru4=&quot;test4&quot;&gt;
    &lt;PlanCargo Duration=&quot;45&quot; BillID=&quot;&quot; Weight=&    quot;100&quot; Units=&quot;100.0&quot; XUnitTypeID=&quot;9&quot; Action=&quot;Pick&quot;     /&gt;
    &lt;/PlanStop&gt; />

因此,换句话说,我需要把现有的XML输出,并把它的属性,同时执行一些字符转换。

是的,这是非常丑陋的,但是这也是他们想要的。 我在想使另一个XSL转换时的<,>,将在XML输出复制从原来的XSL转换,并将其放置在一个属性的,“等成<,>,”等(不知道他们叫什么)。

我已经冲刷了解决方案互联网,但我似乎无法找到任何是很喜欢这个(我想像这是因为这是一个荒谬的要求)。 如果需要的话我可以提供我原来的XSL,但如果可能的话,我宁愿不改变它。

提前致谢!

Answer 1:

我想拯救自己的时间,从别人的愚蠢努力和抑郁症,并实施这与使用一个微小的扩展功能一个微小的转变

下面是例如使用.NET XslCompiledTransform XSLT处理器:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:msxsl="urn:schemas-microsoft-com:xslt"
 xmlns:my="my:my" exclude-result-prefixes="msxsl my">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="/*">
  <t stupid="{my:stringize(.)}"/>
 </xsl:template>

 <msxsl:script language="c#" implements-prefix="my">
  public string stringize(XPathNavigator doc)
  {
   return doc.InnerXml;
  }
 </msxsl:script>
</xsl:stylesheet>

当在任何XML文档应用时,它产生与所述顶部元件stupid包含顶部元件的主体的转义表示属性。

例如,当转换应用于此XML文档上

<t>
  <a>
    <b x="y">
      <!--  Comment here -->
      <?aPI ?>
    </b>
  </a>
</t>

想要的结果产生

<t stupid="&#xD;&#xA;  &lt;a&gt;&#xD;&#xA;    &lt;b x=&quot;y&quot;&gt;&#xD;&#xA;      &lt;!--  Comment here --&gt;&#xD;&#xA;      &lt;?aPI?&gt;&#xD;&#xA;    &lt;/b&gt;&#xD;&#xA;  &lt;/a&gt;&#xD;&#xA;" />

实施同样的想法最有可能转换可用于几乎与本身可以在各种编程语言编写的扩展功能, 每一个XSLT处理器编写



Answer 2:

我与其他评论者同意,在属性中插入XML文档的XML词汇完全是疯狂的。 数据的拥有者将失去这么大的权力和灵活性,并获得任何回报。 但是,如果你真的没有选择,然后自杀(玩笑)。 如果此选项是难吃了你,那么你可以连载你内心的XML与像这样的模板?

<xsl:template match="*" mode="serialise">
  <xsl:value-of select="concat('&lt;',local-name(),' ')">
  <xsl:apply-templates select="@*" mode="serialise">
  <xsl:value-of select="' &gt;'">
  <xsl:apply-templates select="*|text()" mode="serialise">
  <xsl:value-of select="concat('&lt;/',local-name(),' &gt;')">
</xsl:template>

<xsl:template match="@*" mode="serialise">
  <xsl:value-of select="concat(local-name(),'=&quot;',.,'&quot; ')">
</xsl:template>

<xsl:template match="text()" mode="serialise">
  <xsl:value-of select=".">
</xsl:template>

取与要编码为XML词汇和调用的<xsl:应用模板>内部结构的根元素与@模式=“串行化处理”。 抓住这一调用的输出到一个字符串变量。 然后,您可以将字符串变量的内容是什么,曾经在你喜欢的结果树属性。

警告

这些简单的模板不处理意见(),处理的指令()和文档类型。 另外,作为每XDM(违背DOM),相邻的文本类型的节点(文本,CDATA,字符引用等)将被合并。 此外,这并不与命名空间的工作。



Answer 3:

序列化XML作为转义文本的XSLT样式表,可以发现http://code.google.com/p/httpfox/source/browse/trunk/chrome/content/XMLPrettyPrint.xsl?r=3它输出HTML,但你可以很容易地适应输出XML,大多是通过删除不需要的东西,比如扩展。

唯一棘手的部分可能会得到从现有的XSL作为输入到新模板XML输出。 如果要实现后者作为一个单独的样式表,或者如果您使用XSLT 2.0,这将是没有问题的。 否则,您可能需要使用node-set()扩展功能。

有迹象表明,可以详细阐述了上述的几个方面。 奥莱如果你卡住! HTH。

PS其实,自从我开始这个职位,@Sean张贴了他的答案,这更容易适应比上面的样式表来使用。



Answer 4:

基本上,你需要序列化的XML,获取序列化为一个字符串的结果,然后写这个字符串作为其值的属性。 有没有在XSLT 1.0或XSLT 2.0这样做的直接方式。 XSLT 3.0有一个函数fn:连载()专为满足这一要求,而且它在最近版本的撒克逊人的实现。 (撒克逊的早期版本中引入了这个念头一撒克逊:序列化()扩展功能,您可能会发现类似功能的其他产品,或者你可以写自己的。)实现在XSLT串行本身当然是可能的,因为别人建议; 这只是相当繁琐。



文章来源: Output entire XML as an attribute