2014-09-13 4 views
1

Есть ли способ в C++, используя TinyXML, TinyXpath, например этого, строка, содержащее:Есть ли способ, чтобы удалить пространство имен из XML-тегов с использованием C++/подталкивания или с помощью какой-либо другой библиотеки

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

превращается в

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

EDIT:

Я использовал Tinyxml и Tinyxpath.

Мой рабочий был:

а) Создание РОМА дерева с помощью TinyXML

б) Пропустите РОМ дерево 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); 
    } 
} 

Так ли рабочий процесс изменен:

а) Создание domtree с помощью TinyXML

б) удаление имен из domtree с помощью RemoveAllNamespaces(domtree.Root())

с) Проходят модифицированную-domtree к Tinyxpath для Xpath оценок

+1

tinyxml - очень маленькая и простая библиотека для работы с xml. – 2014-09-13 10:38:59

+0

@Status, я использую tinyxml + tinyxpath. И устраняем проблему выше, пересекая DOM-дерево tinyxml и делая node-> SetValue (RemoveNamespaceFromString (node-> Getvalue())) для каждого элемента: node. – fizzbuzz

ответ

1

Ok, в ответ на вопрос, отредактированной несколько примечаний:

  • , что на самом деле не лечат пространства имен (рассмотрим 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); 
    } 
} 

На my MSVC test печатает

<?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> 
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> 
+0

Нет необходимости в C/C++/C#/Python/ :-) Когда я прочитал вопрос, это решение сразу же возникло из виду. – Clearer

+0

ОК. Но мне нужно сделать это программно. Поэтому, я думаю, я могу использовать libxml (или некоторую другую lib), чтобы делать то, что @sehe предлагает. – fizzbuzz

+0

Я использовал tinyxml + tinyxpath. И устраняем проблему выше, пересекая DOM-дерево tinyxml и делая node-> SetValue (RemoveNamespaceFromString (node-> Getvalue())) для каждого элемента: node. Тем не менее, спасибо за предложения – fizzbuzz