XSLT - how to output namespace prefix but not name

2019-09-05 18:15发布

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

标签: xml xslt
4条回答
爷的心禁止访问
2楼-- · 2019-09-05 18:44

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.

查看更多
倾城 Initia
3楼-- · 2019-09-05 18:47

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

查看更多
做自己的国王
4楼-- · 2019-09-05 18:59

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.

查看更多
干净又极端
5楼-- · 2019-09-05 19:04

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!

查看更多
登录 后发表回答