Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Xml XSL仅转换特定命名空间中的元素_Xml_Xslt_Xml Namespaces_Xalan - Fatal编程技术网

Xml XSL仅转换特定命名空间中的元素

Xml XSL仅转换特定命名空间中的元素,xml,xslt,xml-namespaces,xalan,Xml,Xslt,Xml Namespaces,Xalan,我有一个xml文档,它的结构有点像这样:- <catalog xmlns="format_old" xmlns:final="format_new"> <final:book> <final:title>blah</final:title> <final:author>more blah</final:author> </final:book> <book> <

我有一个xml文档,它的结构有点像这样:-

<catalog xmlns="format_old" xmlns:final="format_new">
  <final:book>
    <final:title>blah</final:title>
    <final:author>more blah</final:author>
  </final:book>
  <book>
    <description title="blah2"/>
    <writer name="more blah2"/>
  </book>
</catalog>
<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:orig="format_old"
  xmlns="format_new"/>

<xsl:template match="@*|node()">
  <xsl:copy>
    <xsl:apply-templates select="@*|node()" />
  </xsl:copy>
</xsl:template>

<xsl:template match="//orig:book">
  <xsl:element name="title">
    <xsl:value-of select="./orig:description/@title" />
  </xsl:element>
  <xsl:element name="author">
    <xsl:value-of select="./orig:writer/@name" />
  </xsl:element>
</xsl:template>

</xsl:stylesheet>

废话
更多废话
显然,这是问题的简化版本。我想做的是将其转换为如下内容:

<catalog xmlns="format_new">
  <book>
    <title>blah</title>
    <author>more blah</author>
  </book>
  <book>
    <title>blah2</title>
    <author>more blah2</author>
  </book>
</catalog>

废话
更多废话
废话
更多废话
我现在拥有的样式表如下:-

<catalog xmlns="format_old" xmlns:final="format_new">
  <final:book>
    <final:title>blah</final:title>
    <final:author>more blah</final:author>
  </final:book>
  <book>
    <description title="blah2"/>
    <writer name="more blah2"/>
  </book>
</catalog>
<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:orig="format_old"
  xmlns="format_new"/>

<xsl:template match="@*|node()">
  <xsl:copy>
    <xsl:apply-templates select="@*|node()" />
  </xsl:copy>
</xsl:template>

<xsl:template match="//orig:book">
  <xsl:element name="title">
    <xsl:value-of select="./orig:description/@title" />
  </xsl:element>
  <xsl:element name="author">
    <xsl:value-of select="./orig:writer/@name" />
  </xsl:element>
</xsl:template>

</xsl:stylesheet>

这会给我一个如下输出:-

<catalog xmlns="format_old">
  <book xmlns="format_new">
    <title>blah</title>
    <author>more blah</author>
  </book>
  <book xmlns:orig="format_old" xmlns="format_new">
    <title>blah2</title>
    </author>more blah2</author>
  </book>
</catalog>

废话
更多废话
废话
更多废话
此样式表有两个问题:-

1.(主要问题)复制根元素,而不是更改根元素的默认命名空间。因此,catalog元素基本上仍然是名称空间格式

2.)(小问题)这将把元素转换为:-

<book xmlns:orig="format_old" xmlns="format_new">
  ...
</book>

...
而不是从根元素中提取名称空间,将其保持为

<book>
  ...
</book>

...

我错过了什么?我使用的是Xalan-C。

我认为应该做以下几点:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
    xmlns="format_new"
    xmlns:ns1="format_old"
    exclude-result-prefixes="ns1"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="@* | text() | comment() | processing-instruction()">
  <xsl:copy/>
</xsl:template>

<xsl:template match="*">
  <xsl:element name="{local-name()}">
    <xsl:apply-templates select="@* | node()"/>
  </xsl:element>
</xsl:template>

<xsl:template match="ns1:book/ns1:description[@title]">
  <title>
    <xsl:value-of select="@title"/>
  </title>
</xsl:template>

<xsl:template match="ns1:book/ns1:writer[@name]">
  <author>
    <xsl:value-of select="@name"/>
  </author>
</xsl:template>

</xsl:stylesheet>

Saxon 6.5.5将您的输入转换为

<?xml version="1.0" encoding="utf-8"?><catalog xmlns="format_new">
  <book>
    <title>blah</title>
    <author>more blah</author>
  </book>
  <book>
    <title>blah2</title>
    <author>more blah2</author>
  </book>
</catalog>

废话
更多废话
废话
更多废话

我认为应该采取以下措施:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
    xmlns="format_new"
    xmlns:ns1="format_old"
    exclude-result-prefixes="ns1"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="@* | text() | comment() | processing-instruction()">
  <xsl:copy/>
</xsl:template>

<xsl:template match="*">
  <xsl:element name="{local-name()}">
    <xsl:apply-templates select="@* | node()"/>
  </xsl:element>
</xsl:template>

<xsl:template match="ns1:book/ns1:description[@title]">
  <title>
    <xsl:value-of select="@title"/>
  </title>
</xsl:template>

<xsl:template match="ns1:book/ns1:writer[@name]">
  <author>
    <xsl:value-of select="@name"/>
  </author>
</xsl:template>

</xsl:stylesheet>

Saxon 6.5.5将您的输入转换为

<?xml version="1.0" encoding="utf-8"?><catalog xmlns="format_new">
  <book>
    <title>blah</title>
    <author>more blah</author>
  </book>
  <book>
    <title>blah2</title>
    <author>more blah2</author>
  </book>
</catalog>

废话
更多废话
废话
更多废话

你很接近了。您的默认模板将拾取您没有其他模板的所有内容

您的第一个问题是,他们正在提取orig:catalog元素并将其原封不动地写出来,这不是您想要的。简单修复:为它添加一个模板

第二个问题是管理输出中的命名空间声明。在这里,有几种技术可能会有所帮助:

  • 仔细阅读xsl:exclude结果前缀在spec或您最喜欢的XSLT引用中的文档;使用它告诉处理器,您不需要为旧名称空间声明名称空间

  • 如果要利用文本结果元素的输出总是携带样式表中LRE上的所有inscope命名空间前缀这一事实,请使用xsl:element构造函数而不是文本结果元素。有关更多详细信息,请参阅

  • 在SAX或您最喜欢的编辑器中编写一个简单的过滤器,使您能够完全控制名称空间的声明位置和方式。(XSLT的设计认为您应该非常担心名称空间声明,因此很难很好地控制它们。)

  • 训练自己不要太在意输出是否有一些无关的名称空间声明,并编写下游使用者来做正确的事情,只要所有内容都绑定正确,这样他们就不会被无关的名称空间声明所困扰


不同的人用这些不同的技术取得不同程度的成功;就我自己而言,我发现最后一个特别有效,我只担心其他的当我崩溃时。

你很接近了。您的默认模板将拾取您没有其他模板的所有内容

您的第一个问题是,他们正在提取orig:catalog元素并将其原封不动地写出来,这不是您想要的。简单修复:为它添加一个模板

第二个问题是管理输出中的命名空间声明。在这里,有几种技术可能会有所帮助:

  • 仔细阅读xsl:exclude结果前缀在spec或您最喜欢的XSLT引用中的文档;使用它告诉处理器,您不需要为旧名称空间声明名称空间

  • 如果要利用文本结果元素的输出总是携带样式表中LRE上的所有inscope命名空间前缀这一事实,请使用xsl:element构造函数而不是文本结果元素。有关更多详细信息,请参阅

  • 在SAX或您最喜欢的编辑器中编写一个简单的过滤器,使您能够完全控制名称空间的声明位置和方式。(XSLT的设计认为您应该非常担心名称空间声明,因此很难很好地控制它们。)

  • 训练自己不要太在意输出是否有一些无关的名称空间声明,并编写下游使用者来做正确的事情,只要所有内容都绑定正确,这样他们就不会被无关的名称空间声明所困扰

不同的人用这些不同的技术取得不同程度的成功;就我自己而言,我发现最后一个特别有效,我只担心其他的当我崩溃的时候