在序列化DOM中调整XML名称空间声明样式

时间:2018-01-17 14:12:06

标签: java xml dom jax-ws

请考虑生成的两个等效xml文档作为对SOAP调用的响应。

文件一:

<?xml version="1.0" encoding="utf-8"?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
  <S:Header>
    <ns2:ServerVersionInfo xmlns:ns3="http://schemas.microsoft.com/exchange/services/2006/messages" xmlns:ns2="http://schemas.microsoft.com/exchange/services/2006/types" MajorVersion="15" MinorVersion="1" MajorBuildNumber="845" MinorBuildNumber="34"/>
  </S:Header>
  <S:Body>
    <ns3:GetUserAvailabilityResponse xmlns:ns3="http://schemas.microsoft.com/exchange/services/2006/messages" xmlns:ns2="http://schemas.microsoft.com/exchange/services/2006/types">
      <ns3:FreeBusyResponseArray>
        <ns3:FreeBusyResponse>
          <ns3:ResponseMessage ResponseClass="Success">
            <ns3:ResponseCode>NoError</ns3:ResponseCode>
          </ns3:ResponseMessage>
          <ns3:FreeBusyView>
            <ns2:FreeBusyViewType>MergedOnly</ns2:FreeBusyViewType>
            <ns2:MergedFreeBusy>0000</ns2:MergedFreeBusy>
          </ns3:FreeBusyView>
        </ns3:FreeBusyResponse>
      </ns3:FreeBusyResponseArray>
    </ns3:GetUserAvailabilityResponse>
  </S:Body>
</S:Envelope>

文件二:

<?xml version="1.0" encoding="utf-8"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Header>
    <h:ServerVersionInfo xmlns:h="http://schemas.microsoft.com/exchange/services/2006/types" xmlns="http://schemas.microsoft.com/exchange/services/2006/types" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" MajorVersion="15" MinorVersion="1" MajorBuildNumber="845" MinorBuildNumber="34"/>
  </s:Header>
  <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <GetUserAvailabilityResponse xmlns="http://schemas.microsoft.com/exchange/services/2006/messages">
      <FreeBusyResponseArray>
        <FreeBusyResponse>
          <ResponseMessage ResponseClass="Success">
            <ResponseCode>NoError</ResponseCode>
          </ResponseMessage>
          <FreeBusyView>
            <FreeBusyViewType xmlns="http://schemas.microsoft.com/exchange/services/2006/types">MergedOnly</FreeBusyViewType>
            <MergedFreeBusy xmlns="http://schemas.microsoft.com/exchange/services/2006/types">0000</MergedFreeBusy>
          </FreeBusyView>
        </FreeBusyResponse>
      </FreeBusyResponseArray>
    </GetUserAvailabilityResponse>
  </s:Body>
</s:Envelope>

如果我错了,请纠正我,但除了xml名称空间声明样式之外,这些DOM在语义上看起来相似。我想从我的java应用程序中调整jax-ws输出,从文档二的样式中调整样式。 如果需要,我可以使用javax.xml.transform.Transformer重新处理DOM。

2 个答案:

答案 0 :(得分:1)

你可以在XSLT中这样做:

<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">    
<xsl:variable name="bindings">
      <ns prefix="s:" uri="http://schemas.xmlsoap.org/soap/envelope/"/>
      <ns prefix="h:" uri="http://schemas.microsoft.com/exchange/services/2006/types"/>
      <ns prefix="" uri="http://schemas.microsoft.com/exchange/services/2006/messages"/>
    </xsl:variable>

    <xsl:template match="*">
      <xsl:variable name="p" select="$bindings/ns[@uri=namespace-uri(current())]/@prefix"/>
      <xsl:element name="{$p}{local-name()}" namespace="{namespace-uri()}">
        <xsl:copy-of select="@*"/>
        <xsl:apply-templates/>
      </xsl:element>
    </xsl:template>
</xsl:transform>

现在已经过测试(虽然没有使用xsltproc)。

它提供了“Document two”的输出,但FreeBusyViewType和MergedFreeBusy使用名称空间前缀“h”而不是默认名称空间中没有前缀。您需要进一步调整才能更改,因为我的代码会生成一个文档,其中给定命名空间中的所有元素都具有相同的前缀。我不知道你为什么要优先考虑你的输出。 (事实上​​,说实话,我不知道这个小练习的重点是什么。为什么会有人关心?)

答案 1 :(得分:1)

@ mickael-kay答案几乎是正确的。以下样式表进行了正确的转换:

<?xml version="1.0"?>

<xsl:stylesheet version="1.0"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:template match="*">
    <xsl:element name="{local-name()}" namespace="{namespace-uri()}">
      <xsl:copy-of select="@*"/>
      <xsl:apply-templates/>
    </xsl:element>
  </xsl:template>

</xsl:stylesheet>

使用xsltproc运行时会得到以下结果:

<?xml version="1.0"?>
<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
  <Header>
    <ServerVersionInfo xmlns="http://schemas.microsoft.com/exchange/services/2006/types" MajorVersion="15" MinorVersion="1" MajorBuildNumber="845" MinorBuildNumber="34"/>
  </Header>
  <Body>
    <GetUserAvailabilityResponse xmlns="http://schemas.microsoft.com/exchange/services/2006/messages">
      <FreeBusyResponseArray>
        <FreeBusyResponse>
          <ResponseMessage ResponseClass="Success">
            <ResponseCode>NoError</ResponseCode>
          </ResponseMessage>
          <FreeBusyView>
            <FreeBusyViewType xmlns="http://schemas.microsoft.com/exchange/services/2006/types">MergedOnly</FreeBusyViewType>
            <MergedFreeBusy xmlns="http://schemas.microsoft.com/exchange/services/2006/types">0000</MergedFreeBusy>
          </FreeBusyView>
        </FreeBusyResponse>
      </FreeBusyResponseArray>
    </GetUserAvailabilityResponse>
  </Body>
</Envelope>

这对我来说是正确的。