Reading XML file in bash script makes the XML invalid

155 Views Asked by At

I'm trying to load an XML file from file in order to send it to my DYMO label printer.

The Curl command that I execute to print a label from XML file is

curl --location 'http://127.0.0.1:41951/DYMO/DLS/Printing/PrintLabel' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'printerName='"$printerName"'' \
--data-urlencode 'labelXml='"$labelContent"'' \
--data-urlencode 'labelSetXml=' \
--data-urlencode 'printParamsXml='

If I manually put the content inside labelContent (like shown below) it works and prints my label:

labelContent='<?xml version="1.0" encoding="utf-8"?> <DesktopLabel Version="1"> <DYMOLabel Version="3"> <Description>DYMO Label</Description> <Orientation>Landscape</Orientation> <LabelName>ReturnAddressInt</LabelName> <InitialLength>0</InitialLength> <BorderStyle>SolidLine</BorderStyle> <DYMORect> <DYMOPoint> <X>0.09</X> <Y>0.05666666</Y> </DYMOPoint> <Size> <Width>1.976667</Width> <Height>0.9033334</Height> </Size> </DYMORect> <BorderColor> <SolidColorBrush> <Color A="1" R="0" G="0" B="0"></Color> </SolidColorBrush> </BorderColor> <BorderThickness>1</BorderThickness> <Show_Border>False</Show_Border> <DynamicLayoutManager> <RotationBehavior>ClearObjects</RotationBehavior> <LabelObjects> <TextObject> <Name>MODEL</Name> <Brushes> <BackgroundBrush> <SolidColorBrush> <Color A="0" R="1" G="1" B="1"></Color> </SolidColorBrush> </BackgroundBrush> <BorderBrush> <SolidColorBrush> <Color A="1" R="0" G="0" B="0"></Color> </SolidColorBrush> </BorderBrush> <StrokeBrush> <SolidColorBrush> <Color A="1" R="0" G="0" B="0"></Color> </SolidColorBrush> </StrokeBrush> <FillBrush> <SolidColorBrush> <Color A="0" R="0" G="0" B="0"></Color> </SolidColorBrush> </FillBrush> </Brushes> <Rotation>Rotation0</Rotation> <OutlineThickness>1</OutlineThickness> <IsOutlined>False</IsOutlined> <BorderStyle>SolidLine</BorderStyle> <Margin> <DYMOThickness Left="0" Top="0" Right="0" Bottom="0" /> </Margin> <HorizontalAlignment>Center</HorizontalAlignment> <VerticalAlignment>Middle</VerticalAlignment> <FitMode>None</FitMode> <IsVertical>False</IsVertical> <FormattedText> <FitMode>None</FitMode> <HorizontalAlignment>Center</HorizontalAlignment> <VerticalAlignment>Middle</VerticalAlignment> <IsVertical>False</IsVertical> <LineTextSpan> <TextSpan> <Text>test</Text> <FontInfo> <FontName>Helvetica</FontName> <FontSize>7.5</FontSize> <IsBold>False</IsBold> <IsItalic>False</IsItalic> <IsUnderline>False</IsUnderline> <FontBrush> <SolidColorBrush> <Color A="1" R="0" G="0" B="0"></Color> </SolidColorBrush> </FontBrush> </FontInfo> </TextSpan> </LineTextSpan> </FormattedText> <ObjectLayout> <DYMOPoint> <X>0.11</X> <Y>0.6113067</Y> </DYMOPoint> <Size> <Width>1.916667</Width> <Height>0.2083333</Height> </Size> </ObjectLayout> </TextObject> </LabelObjects> </DynamicLayoutManager> </DYMOLabel> <LabelApplication>Blank</LabelApplication> <DataTable> <Columns></Columns> <Rows></Rows> </DataTable> </DesktopLabel>'

However loading the exact same XML from file it does not work. The entire function looks like this:

printLabel()
{
    echo "Printing $1"

    labelContent=`cat $1`

    #labelContent='COPY CONTENT OF ECHO HERE, UNCOMMENT, AND WILL WORK...'

    printerName="DYMO LabelWriter 4XL"

    # Verifying here on the output that the content of the file is ok and it looks perfect
    echo $labelContent

    curl --location 'http://127.0.0.1:41951/DYMO/DLS/Printing/PrintLabel' \
    --header 'Content-Type: application/x-www-form-urlencoded' \
    --data-urlencode 'printerName='"$printerName"'' \
    --data-urlencode 'labelXml='"$labelContent"'' \
    --data-urlencode 'labelSetXml=' \
    --data-urlencode 'printParamsXml='
}

However when loading this file from right from the file system (by executing the method like this printLabel /Users/myusername/Documents/test.dymo it throws me an error:

Printing labels...
Printing test.dymo
[FULL XML OUTPUT HERE]
Error printing label. Exception: Data at the root level is invalid. Line 1, position 1.%

It seems like the content that I'm reading from file is not exactly the same (maybe with the double quotes or so) which causes the XML validation to fail on it.

If I remove the <?xml version="1.0" encoding="utf-8"?> line from the XML file I get a similar result. With manual copy/paste of the echoed XML it works, but then the error from the XML parser is slightly different:

Printing labels...
Printing test.dymo
<DesktopLabel Version="1"> <DYMOLabel Version="3"> <Description>DYMO Label</Description> <Orientation>Landscape</Orientation> <LabelName>ReturnAddressInt</LabelName> <InitialLength>0</InitialLength> <BorderStyle>SolidLine</BorderStyle> <DYMORect> <DYMOPoint> <X>0.09</X> <Y>0.05666666</Y> </DYMOPoint> <Size> <Width>1.976667</Width> <Height>0.9033334</Height> </Size> </DYMORect> <BorderColor> <SolidColorBrush> <Color A="1" R="0" G="0" B="0"></Color> </SolidColorBrush> </BorderColor> <BorderThickness>1</BorderThickness> <Show_Border>False</Show_Border> <DynamicLayoutManager> <RotationBehavior>ClearObjects</RotationBehavior> <LabelObjects> <TextObject> <Name>MODEL</Name> <Brushes> <BackgroundBrush> <SolidColorBrush> <Color A="0" R="1" G="1" B="1"></Color> </SolidColorBrush> </BackgroundBrush> <BorderBrush> <SolidColorBrush> <Color A="1" R="0" G="0" B="0"></Color> </SolidColorBrush> </BorderBrush> <StrokeBrush> <SolidColorBrush> <Color A="1" R="0" G="0" B="0"></Color> </SolidColorBrush> </StrokeBrush> <FillBrush> <SolidColorBrush> <Color A="0" R="0" G="0" B="0"></Color> </SolidColorBrush> </FillBrush> </Brushes> <Rotation>Rotation0</Rotation> <OutlineThickness>1</OutlineThickness> <IsOutlined>False</IsOutlined> <BorderStyle>SolidLine</BorderStyle> <Margin> <DYMOThickness Left="0" Top="0" Right="0" Bottom="0" /> </Margin> <HorizontalAlignment>Center</HorizontalAlignment> <VerticalAlignment>Middle</VerticalAlignment> <FitMode>None</FitMode> <IsVertical>False</IsVertical> <FormattedText> <FitMode>None</FitMode> <HorizontalAlignment>Center</HorizontalAlignment> <VerticalAlignment>Middle</VerticalAlignment> <IsVertical>False</IsVertical> <LineTextSpan> <TextSpan> <Text>test</Text> <FontInfo> <FontName>Helvetica</FontName> <FontSize>7.5</FontSize> <IsBold>False</IsBold> <IsItalic>False</IsItalic> <IsUnderline>False</IsUnderline> <FontBrush> <SolidColorBrush> <Color A="1" R="0" G="0" B="0"></Color> </SolidColorBrush> </FontBrush> </FontInfo> </TextSpan> </LineTextSpan> </FormattedText> <ObjectLayout> <DYMOPoint> <X>0.11</X> <Y>0.6113067</Y> </DYMOPoint> <Size> <Width>1.916667</Width> <Height>0.2083333</Height> </Size> </ObjectLayout> </TextObject> </LabelObjects> </DynamicLayoutManager> </DYMOLabel> <LabelApplication>Blank</LabelApplication> <DataTable> <Columns></Columns> <Rows></Rows> </DataTable> </DesktopLabel>
Error printing label. Exception: Data at the root level is invalid. Line 1, position 39.%
2

There are 2 best solutions below

1
Eric Marceau On

This may sound too simplistic, but ...

Have you tried replacing

--data-urlencode 'labelXml='"$labelContent"''

with

--data-urlencode "labelXml='$labelContent'"
2
Eric Marceau On

Have you tried the alternate approach that is incorporated in this demo script, changing

--data-urlencode 'labelXml='"${labelContent}"''

to

--data-urlencode "labelXml@${labelContentFile}"

I've also reformatted your one-liner for easier viewing.

#!/bin/bash

labelContentFile="testInput.xml"

cat >${labelContentFile} <<"EnDoFiNpUt"
<?xml version="1.0" encoding="utf-8"?>
<DesktopLabel Version="1">
<DYMOLabel Version="3">
    <Description>DYMO Label</Description>
    <Orientation>Landscape</Orientation>
    <LabelName>ReturnAddressInt</LabelName>
    <InitialLength>0</InitialLength>
    <BorderStyle>SolidLine</BorderStyle>
    <DYMORect>
        <DYMOPoint> <X>0.09</X> <Y>0.05666666</Y> </DYMOPoint>
        <Size>
            <Width>1.976667</Width>
            <Height>0.9033334</Height>
        </Size>
    </DYMORect>
    <BorderColor>
        <SolidColorBrush> <Color A="1" R="0" G="0" B="0"></Color> </SolidColorBrush>
    </BorderColor>
    <BorderThickness>1</BorderThickness>
    <Show_Border>False</Show_Border>
    <DynamicLayoutManager>
        <RotationBehavior>ClearObjects</RotationBehavior>
        <LabelObjects>
            <TextObject>
                <Name>MODEL</Name>
                <Brushes>
                    <BackgroundBrush>
                        <SolidColorBrush> <Color A="0" R="1" G="1" B="1"></Color> </SolidColorBrush>
                    </BackgroundBrush>
                    <BorderBrush>
                        <SolidColorBrush> <Color A="1" R="0" G="0" B="0"></Color> </SolidColorBrush>
                    </BorderBrush>
                    <StrokeBrush>
                        <SolidColorBrush> <Color A="1" R="0" G="0" B="0"></Color> </SolidColorBrush>
                    </StrokeBrush>
                    <FillBrush>
                        <SolidColorBrush> <Color A="0" R="0" G="0" B="0"></Color> </SolidColorBrush>
                    </FillBrush>
                </Brushes>
                <Rotation>Rotation0</Rotation>
                <OutlineThickness>1</OutlineThickness>
                <IsOutlined>False</IsOutlined>
                <BorderStyle>SolidLine</BorderStyle>
                <Margin>
                    <DYMOThickness Left="0" Top="0" Right="0" Bottom="0" />
                </Margin>
                <HorizontalAlignment>Center</HorizontalAlignment>
                <VerticalAlignment>Middle</VerticalAlignment>
                <FitMode>None</FitMode>
                <IsVertical>False</IsVertical>
                <FormattedText>
                    <FitMode>None</FitMode>
                    <HorizontalAlignment>Center</HorizontalAlignment>
                    <VerticalAlignment>Middle</VerticalAlignment>
                    <IsVertical>False</IsVertical>
                    <LineTextSpan>
                        <TextSpan>
                            <Text>test</Text>
                            <FontInfo>
                                <FontName>Helvetica</FontName>
                                <FontSize>7.5</FontSize>
                                <IsBold>False</IsBold>
                                <IsItalic>False</IsItalic>
                                <IsUnderline>False</IsUnderline>
                                <FontBrush>
                                    <SolidColorBrush> <Color A="1" R="0" G="0" B="0"></Color> </SolidColorBrush>
                                </FontBrush>
                            </FontInfo>
                        </TextSpan>
                    </LineTextSpan>
                </FormattedText>
                <ObjectLayout>
                    <DYMOPoint> <X>0.11</X> <Y>0.6113067</Y> </DYMOPoint>
                    <Size>
                        <Width>1.916667</Width>
                        <Height>0.2083333</Height>
                    </Size>
                </ObjectLayout>
            </TextObject>
        </LabelObjects>
    </DynamicLayoutManager>
</DYMOLabel>
<LabelApplication>Blank</LabelApplication>
<DataTable>
    <Columns></Columns>
    <Rows></Rows>
</DataTable>
</DesktopLabel>
EnDoFiNpUt


original()
{
    labelContent=$( cat "${labelContentFile}" )

    curl --location 'http://127.0.0.1:41951/DYMO/DLS/Printing/PrintLabel' \
    --header 'Content-Type: application/x-www-form-urlencoded' \
    --data-urlencode 'printerName='"${printerName}"'' \
    --data-urlencode 'labelXml='"${labelContent}"'' \
    --data-urlencode 'labelSetXml=' \
    --data-urlencode 'printParamsXml='
}
#original

revised()
{
    curl --location 'http://127.0.0.1:41951/DYMO/DLS/Printing/PrintLabel' \
    --header 'Content-Type: application/x-www-form-urlencoded' \
    --data-urlencode 'printerName='"${printerName}"'' \
    --data-urlencode "labelXml@${labelContentFile}" \
    --data-urlencode 'labelSetXml=' \
    --data-urlencode 'printParamsXml='
}
revised