@@ -38,6 +38,9 @@ public final class Xml {
3838 private static final String EMPTY_ELEMENT = ELEMENT + CLOSED_ELEMENT ;
3939 private static final String NULL_ELEMENT = ELEMENT + NULL + CLOSED_ELEMENT ;
4040 private static final java .nio .charset .Charset UTF_8 = java .nio .charset .Charset .forName ("UTF-8" );
41+ private static final java .util .regex .Pattern ATTRS = java .util .regex .Pattern .compile (
42+ "((?:(?!\\ s|=).)*)\\ s*?=\\ s*?[\" ']?((?:(?<=\" )(?:(?<=\\ \\ )\" |[^\" ])*|(?<=')"
43+ + "(?:(?<=\\ \\ )'|[^'])*)|(?:(?!\" |')(?:(?!\\ />|>|\\ s).)+))" );
4144
4245 public static class XmlStringBuilder {
4346 public enum Step {
@@ -707,7 +710,7 @@ private static Object getValue(final Object value) {
707710 @ SuppressWarnings ("unchecked" )
708711 private static Map <String , Object > createMap (final org .w3c .dom .Node node ,
709712 final Function <Object , Object > nodeMapper , Map <String , Object > attrMap , int [] uniqueIds ,
710- final Function <Object , Object > valueMapper ) {
713+ final Function <Object , Object > valueMapper , String source , int [] sourceIndex ) {
711714 final Map <String , Object > map = U .newLinkedHashMap ();
712715 map .putAll (attrMap );
713716 final org .w3c .dom .NodeList nodeList = node .getChildNodes ();
@@ -718,14 +721,22 @@ private static Map<String, Object> createMap(final org.w3c.dom.Node node,
718721 final int attributesLength = currentNode .getAttributes () == null
719722 ? 0 : currentNode .getAttributes ().getLength ();
720723 if (currentNode .getNodeType () == org .w3c .dom .Node .ELEMENT_NODE ) {
724+ sourceIndex [0 ] = source .indexOf ("<" + name , sourceIndex [0 ]) + name .length () + 2 ;
721725 final Map <String , Object > attrMapLocal = U .newLinkedHashMap ();
722- for (int indexAttr = 0 ; indexAttr < attributesLength ; indexAttr += 1 ) {
723- final org .w3c .dom .Node currentNodeAttr = currentNode .getAttributes ().item (indexAttr );
724- addNodeValue (attrMapLocal , '-' + currentNodeAttr .getNodeName (),
725- currentNodeAttr .getTextContent (), nodeMapper , uniqueIds );
726+ if (attributesLength > 0 ) {
727+ final java .util .regex .Matcher matcher = ATTRS .matcher (source .substring (
728+ sourceIndex [0 ], source .indexOf (">" , sourceIndex [0 ])));
729+ while (matcher .find ()) {
730+ addNodeValue (attrMapLocal , '-' + matcher .group (1 ), matcher .group (2 ), nodeMapper , uniqueIds );
731+ }
726732 }
727- value = createMap (currentNode , nodeMapper , attrMapLocal , uniqueIds , valueMapper );
733+ value = createMap (currentNode , nodeMapper , attrMapLocal , uniqueIds , valueMapper , source , sourceIndex );
728734 } else {
735+ if (COMMENT .equals (name )) {
736+ sourceIndex [0 ] = source .indexOf ("-->" , sourceIndex [0 ]) + 3 ;
737+ } else if (CDATA .equals (name )) {
738+ sourceIndex [0 ] = source .indexOf ("]]>" , sourceIndex [0 ]) + 3 ;
739+ }
729740 value = currentNode .getTextContent ();
730741 }
731742 if (TEXT .equals (name ) && valueMapper .apply (value ).toString ().isEmpty ()) {
@@ -794,7 +805,7 @@ public static Object fromXml(final String xml, final Function<Object, Object> va
794805 public Object apply (Object object ) {
795806 return object ;
796807 }
797- }, Collections .<String , Object >emptyMap (), new int [] {1 , 1 , 1 }, valueMapper );
808+ }, Collections .<String , Object >emptyMap (), new int [] {1 , 1 , 1 }, valueMapper , xml , new int [] { 0 } );
798809 if (document .getXmlEncoding () != null && !"UTF-8" .equalsIgnoreCase (document .getXmlEncoding ())) {
799810 ((Map ) result ).put (ENCODING , document .getXmlEncoding ());
800811 } else if (((Map .Entry ) ((Map ) result ).entrySet ().iterator ().next ()).getKey ().equals ("root" )
@@ -839,7 +850,7 @@ public Object apply(Object object) {
839850 public Object apply (Object object ) {
840851 return String .valueOf (object ).trim ();
841852 }
842- });
853+ }, xml , new int [] { 0 } );
843854 } catch (Exception ex ) {
844855 throw new IllegalArgumentException (ex );
845856 }
0 commit comments