如何使用xslt(版本1.0)替换xml结构的子字符串

时间:2014-05-13 15:22:36

标签: xml xslt replace xalan

我有一个大的xml文件,其中文件的一部分具有以下结构:

xml structure

如何使用XSLT将xml元素中的所有“abc ...”替换为“xyz ...”?

基本条件是:

  • xml - 版本1.0
  • 没有EXSLT,没有Java
  • 仅对节点的子节点进行替换:“base.data.row”
  • 我将使用C ++中的XalanTransformer进行转换

我现在得到的只是XSLT中的身份转换,现在我搜索了一种替换节点“base.data.row”的子节点名称的方法。 但我不知道如何。

这里是xml:

<?xml version="1.0" encoding="utf-8"?>
<base>
  <data>
    <row type="">
      <abc_dimension />
      <abc_weight />
      <numOf />
      <abcValues>
        <val1 />
        <val2 />
      </abcValues>
      <graph />
    </row>
    <row type="">
      <abc_dimension />
      <abc_weight />
      <numOf />
      <abcValues>
        <val1 />
        <val2 />
      </abcValues>
      <graph />
    </row>
    <row type="">
      <abc_dimension />
      <abc_weight />
      <numOf />
      <abcValues>
        <val1 />
        <val2 />
      </abcValues>
      <graph />
    </row>
  </data>
</base>

我在这里尝试了“michael.hor257k”的xslt(http://xslttest.appspot.com/)并且它有效! 但是当我在C ++中使用XalanTransformer时,它只返回xml节点的值。 我通过以下方式使用XalanTransformer:

XALAN_USING_XERCES( XMLPlatformUtils );
XALAN_USING_XALAN( XalanTransformer );

XMLPlatformUtils::Initialize();
XalanTransformer::initialize();

const char* xmlIn = "origXML.xml";
const char* xslIn = "transformation_template.xslt"; //the xslt of michael.hor257k
const char* xmlOut = "origXMLTransformed-out.xml"; //returns only the values of the xml nodes

XalanTransformer theXalanTransformer;
int a_errNumber = theXalanTransformer.transform( xmlIn, xslIn, xmlOut );               

XalanTransformer::terminate();
XMLPlatformUtils::Terminate();
XalanTransformer::ICUCleanUp();

修正了它,好像有某个错字。 似乎XalanTransformer使用默认模板规则,这将导致输出整个源文档中的所有文本节点。

2 个答案:

答案 0 :(得分:2)

尝试:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

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

<!-- rename -->
<xsl:template match="base/data/row/*[starts-with(name(), 'abc')]">
    <xsl:element name="xyz{substring-after(name(), 'abc')}">
        <xsl:apply-templates select="@*|node()"/>
    </xsl:element>
</xsl:template>

</xsl:stylesheet>

答案 1 :(得分:0)

尝试使用以下方式,这可能会对您有所帮助。我尝试编写一些示例xml和xsl来处理元素名称,它工作正常。

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="2.0">
    <xsl:template match="/">
        <xsl:element name="base">
                    <xsl:for-each select="base/data">
                <xsl:element name="row">
                    <xsl:for-each select="row/*">
                        <xsl:choose>
                            <xsl:when test="starts-with(name(.),'abc')">
                                <xsl:element name="{concat('pqr', substring-after(name(.), 'abc'))}">
                                    <xsl:value-of select="." />
                                </xsl:element>
                            </xsl:when>
                            <xsl:otherwise>
                                <xsl:element name="{name(.)}">
                                    <xsl:value-of select="." />
                                </xsl:element>
                            </xsl:otherwise>
                        </xsl:choose>
                    </xsl:for-each>
                </xsl:element>
            </xsl:for-each>
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>

我试过的样本xml。

<base>
  <data>
    <row>
      <type>110</type>
      <abc_dimension>dimension value 1</abc_dimension>
      <abc_weight>weight value 1</abc_weight>
      <nomof>x1</nomof>
    </row>
    <row>
      <type>111</type>
      <abc_dimension>dimension value 2</abc_dimension>
      <abc_weight>weight value 2</abc_weight>
      <nomof>x2</nomof>
    </row>
  </data>
</base>

谢谢,
拉夫