XSLT - how to output namespace prefix but not name

2019-09-05 19:00发布

问题:

I need to produce this output which includes a namespace alias but not the definition:

<my:Risks>
  <my:Risk>
    <my:ID>1</my:ID> 
    <my:Description><div>test1</div></my:Description>
  </my:Risk>
  <my:Risk>
    <my:ID>2</my:ID> 
    <my:Description><div>test2</div></my:Description>
  </my:Risk>
</my:Risks>

from this input:

<ArrayOfRisk>
    <Risk>
      <ID>1</ID> 
      <Description><div>test1</div></Description> 
    </Risk>
    <Risk>
      <ID>2</ID> 
      <Description><div>test2</div></Description> 
    </Risk>
</ArrayOfRisk>

I am using this XSLT, but need to know how not to have the "my" namespace definition appear in the output:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:my='http://blaha.com'>
  <xsl:template match="/">
    <my:Risks>
      <xsl:apply-templates select="//Risk"/>
    </my:Risks>
  </xsl:template>

  <xsl:template match="Risk">
    <my:Risk>
      <xsl:apply-templates/>
    </my:Risk>
  </xsl:template>

  <xsl:template match="ID">
    <my:ID><xsl:value-of select="." /></my:ID>
  </xsl:template>

  <xsl:template match="Description">
    <my:Description><xsl:copy-of select="node()" /></my:Description>
  </xsl:template>
</xsl:stylesheet>

Thanks in advance

回答1:

The resultant XML will be inserted into an existing doc that has the namespace defined already.

This is not actually a problem as redundant namespace declarations do no harm.

<foo:bar xmlns:foo="http://example.com">
  <foo:baz xmlns:foo="http://example.com"/>
</foo:bar>

is exactly the same as

<foo:bar xmlns:foo="http://example.com">
  <foo:baz />
</foo:bar>

as far as any namespace-aware XML parser is concerned. If you want to avoid including the namespace declarations in the first place then you would need to assemble your final document using XML-aware tools rather than simply string concatenation. For example in Java you could build up your XML using something like a StAX XMLStreamWriter, then when you reach the point where the transformation result should be inserted you pass the open writer to the Transformer (in a StAXResult) and it will write the output in the context of the existing namespace declarations and will know not to add extra redundant ones.



回答2:

The proposed out XML is invalid:

<my:Risks>
  <my:Risk>
    <my:ID>1</my:ID> 
    <my:Description><div>test1</div></my:Description>
  </my:Risk>
  <my:Risk>
    <my:ID>2</my:ID> 
    <my:Description><div>test2</div></my:Description>
  </my:Risk>
</my:Risks>

Namespace prefixes must be defined. An XSLT engine will always output valid XML, so will not be able to produce the above.

XML is about data - not cosmetics!



回答3:

XSLT cannot produce output that is not namespace-well-formed.



回答4:

Well I guess everyone is correct here. For my purposes string manipulation works. But I have learned a bit more about xslt and namespaces. Thanks all.



标签: xml xslt