1

在C++中有没有办法,使用TinyxmlTinyXpath,这样,一个字符串包含:

<ns:abcd>
  <ns:defg>
    <ns:hijk>
    </ns:hijk>
  </ns:defg>
</ns:abcd>

转换为

<abcd>
  <defg>
    <hijk>
    </hijk>
  </defg>
</abcd>

编辑:

我使用的是 Tinyxml 和 Tinyxpath。

我的工作流程是:

a) 使用 TinyXML 创建一个 dom-tree

b) 将 dom-tree 传递给 Tinyxpath 以进行 xpath 评估

要添加命名空间删除,我使用了以下功能:

void  RemoveAllNamespaces(TiXmlNode* node)
{
    TiXmlElement* element = node->ToElement();
    if(!element){
        return; 
    }
    std::string elementName = element->Value(); 
    std::string::size_type idx = elementName.rfind(':');
    if(idx != std::string::npos)
    { 
        element->SetValue(elementName.substr( idx + 1).c_str());
    }
    TiXmlNode* child = element->IterateChildren(NULL);
    while(child)
    {
        RemoveAllNamespaces(child);
        child = element->IterateChildren(child);
    }
}

因此工作流程更改为:

a) 使用 TinyXML 创建一个 dom-tree

b) 使用从 domtree 中删除命名空间RemoveAllNamespaces(domtree.Root() )

c) 将 modified-dom-tree 传递给 Tinyxpath 以进行 xpath 评估

4

2 回答 2

2

我会在这里使用 XSLT 转换:

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output omit-xml-declaration="yes" indent="yes" />

    <xsl:template match="*">
        <xsl:element name="{name()}" namespace=""><xsl:apply-templates select="node()|@*"/></xsl:element>
    </xsl:template>
    <xsl:template match="@*">
        <xsl:attribute name="{name()}" namespace=""><xsl:value-of select="."/></xsl:attribute>
    </xsl:template>
</xsl:stylesheet>

请注意,在元素/属性上,namespace=""清除命名空间。您也可以指定不同的命名空间。

input.xml喜欢

<?xml version="1.0"?>
<ns:abcd xmlns:ns="http://bla/bla">
  <ns:defg attr="value">
    <ns:hijk>
    </ns:hijk>
  </ns:defg>
</ns:abcd>

xsltproc xform.xsl input.xml印刷:

<abcd>
<defg attr="value">
    <hijk>
    </hijk>
</defg>
</abcd>
于 2014-09-13T19:46:02.163 回答
1

好的,针对已编辑的问题,请注意以下几点:

  • 这实际上并不处理命名空间(考虑xmlns="http://blabla.com/uri"样式默认命名空间),但这实际上是一个 TinyXml 限制(eek):

    此外,TinyXML 没有处理 XML 名称空间的工具。合格的元素或属性名称保留其前缀,因为 TinyXML 不努力将前缀与命名空间匹配。

  • 它不处理属性(也可以限定)

这是我要做的又快又脏的事情(假设您已经在使用 TIXML_USE_STL):

static inline std::string RemoveNs(std::string const& xmlName)
{
    return xmlName.substr(xmlName.find_last_of(":") + 1);
}

void  RemoveAllNamespaces(TiXmlNode* node)
{
    assert(node);

    if (auto element = node->ToElement()) {
        element->SetValue(RemoveNs(element->Value()));

        for (auto attr = element->FirstAttribute(); attr; attr = attr->Next())
            attr->SetName(RemoveNs(attr->Name()));

        for (auto child = node->IterateChildren(nullptr); child; child = element->IterateChildren(child))
            RemoveAllNamespaces(child);
    }
}

我的 MSVC 测试中,它打印

<?xml version="1.0" standalone="no"?>
<!-- Our: to do list data -->
<ToDo a="http://example.org/uri1">
  <!-- Do I need: a secure PDA? -->
  <Item priority="1" distance="close">Go to the<bold>Toy store!</bold></Item>
  <Item priority="2" distance="none">Do bills</Item>
  <Item priority="2" distance="far &amp; back">Look for Evil Dinosaurs!</Item>
</ToDo>
于 2014-09-16T09:52:48.840 回答